]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - bytecode/CallLinkInfo.cpp
JavaScriptCore-7600.1.4.17.5.tar.gz
[apple/javascriptcore.git] / bytecode / CallLinkInfo.cpp
index 4c108ecf181d594a6a8c3ec2ac36e9505ebdeb78..72575bddcfa09ce6028e972203c43d21342df7a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "CallLinkInfo.h"
 
 #include "DFGOperations.h"
+#include "DFGThunks.h"
+#include "JSCInlines.h"
 #include "RepatchBuffer.h"
+#include <wtf/NeverDestroyed.h>
 
 #if ENABLE(JIT)
 namespace JSC {
 
-void CallLinkInfo::unlink(JSGlobalData& globalData, RepatchBuffer& repatchBuffer)
+void CallLinkInfo::unlink(RepatchBuffer& repatchBuffer)
 {
     ASSERT(isLinked());
     
-    if (isDFG) {
-#if ENABLE(DFG_JIT)
-        repatchBuffer.relink(CodeLocationCall(callReturnLocation), callType == Construct ? DFG::operationLinkConstruct : DFG::operationLinkCall);
-#else
-        ASSERT_NOT_REACHED();
-#endif
-    } else
-        repatchBuffer.relink(CodeLocationNearCall(callReturnLocation), callType == Construct ? globalData.jitStubs->ctiVirtualConstructLink() : globalData.jitStubs->ctiVirtualCallLink());
+    if (Options::showDisassembly())
+        dataLog("Unlinking call from ", callReturnLocation, " to ", pointerDump(repatchBuffer.codeBlock()), "\n");
+
+    repatchBuffer.revertJumpReplacementToBranchPtrWithPatch(RepatchBuffer::startOfBranchPtrWithPatchOnRegister(hotPathBegin), static_cast<MacroAssembler::RegisterID>(calleeGPR), 0);
+    repatchBuffer.relink(
+        callReturnLocation,
+        repatchBuffer.codeBlock()->vm()->getCTIStub(linkThunkGeneratorFor(
+            (callType == Construct || callType == ConstructVarargs)? CodeForConstruct : CodeForCall,
+            isFTL ? MustPreserveRegisters : RegisterPreservationNotRequired)).code());
     hasSeenShouldRepatch = false;
     callee.clear();
+    stub.clear();
 
     // It will be on a list if the callee has a code block.
     if (isOnList())
         remove();
 }
 
+void CallLinkInfo::visitWeak(RepatchBuffer& repatchBuffer)
+{
+    if (isLinked()) {
+        if (stub) {
+            if (!Heap::isMarked(stub->structure())
+                || !Heap::isMarked(stub->executable())) {
+                if (Options::verboseOSR()) {
+                    dataLog(
+                        "Clearing closure call from ", *repatchBuffer.codeBlock(), " to ",
+                        stub->executable()->hashFor(specializationKind()),
+                        ", stub routine ", RawPointer(stub.get()), ".\n");
+                }
+                unlink(repatchBuffer);
+            }
+        } else if (!Heap::isMarked(callee.get())) {
+            if (Options::verboseOSR()) {
+                dataLog(
+                    "Clearing call from ", *repatchBuffer.codeBlock(), " to ",
+                    RawPointer(callee.get()), " (",
+                    callee.get()->executable()->hashFor(specializationKind()),
+                    ").\n");
+            }
+            unlink(repatchBuffer);
+        }
+    }
+    if (!!lastSeenCallee && !Heap::isMarked(lastSeenCallee.get()))
+        lastSeenCallee.clear();
+}
+
+CallLinkInfo& CallLinkInfo::dummy()
+{
+    static NeverDestroyed<CallLinkInfo> dummy;
+    return dummy;
+}
+
 } // namespace JSC
 #endif // ENABLE(JIT)