Replace WTF::move with WTFMove
[WebKit-https.git] / Source / JavaScriptCore / jit / Repatch.cpp
index 655d918..66203d9 100644 (file)
@@ -41,7 +41,6 @@
 #include "LinkBuffer.h"
 #include "JSCInlines.h"
 #include "PolymorphicAccess.h"
-#include "RegExpMatchesArray.h"
 #include "ScratchRegisterAllocator.h"
 #include "StackAlignment.h"
 #include "StructureRareDataInlines.h"
@@ -104,23 +103,18 @@ static void repatchByIdSelfAccess(
     MacroAssembler::repatchInt32(
         stubInfo.callReturnLocation.dataLabel32AtOffset(-(intptr_t)stubInfo.patch.deltaCheckImmToCall),
         bitwise_cast<int32_t>(structure->id()));
-    CodeLocationConvertibleLoad convertibleLoad = stubInfo.callReturnLocation.convertibleLoadAtOffset(stubInfo.patch.deltaCallToStorageLoad);
-    if (isOutOfLineOffset(offset))
-        MacroAssembler::replaceWithLoad(convertibleLoad);
-    else
-        MacroAssembler::replaceWithAddressComputation(convertibleLoad);
 #if USE(JSVALUE64)
     if (compact)
-        MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToLoadOrStore), offsetRelativeToPatchedStorage(offset));
+        MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToLoadOrStore), offsetRelativeToBase(offset));
     else
-        MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToLoadOrStore), offsetRelativeToPatchedStorage(offset));
+        MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToLoadOrStore), offsetRelativeToBase(offset));
 #elif USE(JSVALUE32_64)
     if (compact) {
-        MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToTagLoadOrStore), offsetRelativeToPatchedStorage(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
-        MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToPayloadLoadOrStore), offsetRelativeToPatchedStorage(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
+        MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToTagLoadOrStore), offsetRelativeToBase(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
+        MacroAssembler::repatchCompact(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.deltaCallToPayloadLoadOrStore), offsetRelativeToBase(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
     } else {
-        MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToTagLoadOrStore), offsetRelativeToPatchedStorage(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
-        MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToPayloadLoadOrStore), offsetRelativeToPatchedStorage(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
+        MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToTagLoadOrStore), offsetRelativeToBase(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
+        MacroAssembler::repatchInt32(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.deltaCallToPayloadLoadOrStore), offsetRelativeToBase(offset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
     }
 #endif
 }
@@ -239,6 +233,7 @@ static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, con
         if (!slot.isCacheable() && !slot.isUnset())
             return GiveUpOnCache;
 
+        ObjectPropertyConditionSet conditionSet;
         JSCell* baseCell = baseValue.asCell();
         Structure* structure = baseCell->structure(vm);
 
@@ -259,23 +254,26 @@ static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, con
             && slot.isCacheableValue()
             && slot.slotBase() == baseValue
             && !slot.watchpointSet()
-            && MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToPatchedStorage(slot.cachedOffset()))
+            && isInlineOffset(slot.cachedOffset())
+            && MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToBase(slot.cachedOffset()))
             && action == AttemptToCache
             && !structure->needImpurePropertyWatchpoint()
             && !loadTargetFromProxy) {
             structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
             repatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), operationGetByIdOptimize, true);
-            stubInfo.initGetByIdSelf(vm, codeBlock, structure, slot.cachedOffset());
+            stubInfo.initGetByIdSelf(codeBlock, structure, slot.cachedOffset());
             return RetryCacheLater;
         }
 
         PropertyOffset offset = slot.isUnset() ? invalidOffset : slot.cachedOffset();
-        
-        ObjectPropertyConditionSet conditionSet;
+
         if (slot.isUnset() || slot.slotBase() != baseValue) {
             if (structure->typeInfo().prohibitsPropertyCaching() || structure->isDictionary())
                 return GiveUpOnCache;
             
+            if (slot.isUnset() && structure->typeInfo().getOwnPropertySlotIsImpureForPropertyAbsence())
+                return GiveUpOnCache;
+
             if (slot.isUnset()) {
                 conditionSet = generateConditionsForPropertyMiss(
                     vm, codeBlock, exec, structure, propertyName.impl());
@@ -287,28 +285,36 @@ static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, con
             
             if (!conditionSet.isValid())
                 return GiveUpOnCache;
-            
+
             offset = slot.isUnset() ? invalidOffset : conditionSet.slotBaseCondition().offset();
         }
 
-        AccessCase::AccessType type;
-        if (slot.isCacheableValue())
-            type = AccessCase::Load;
-        else if (slot.isUnset())
-            type = AccessCase::Miss;
-        else if (slot.isCacheableGetter())
-            type = AccessCase::Getter;
-        else
-            type = AccessCase::CustomGetter;
+        JSFunction* getter = nullptr;
+        if (slot.isCacheableGetter())
+            getter = jsDynamicCast<JSFunction*>(slot.getterSetter()->getter());
 
-        newCase = AccessCase::get(
-            vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy,
-            slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
-            slot.isCacheableCustom() ? slot.slotBase() : nullptr);
+        if (!loadTargetFromProxy && getter && AccessCase::canEmitIntrinsicGetter(getter, structure))
+            newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet);
+        else {
+            AccessCase::AccessType type;
+            if (slot.isCacheableValue())
+                type = AccessCase::Load;
+            else if (slot.isUnset())
+                type = AccessCase::Miss;
+            else if (slot.isCacheableGetter())
+                type = AccessCase::Getter;
+            else
+                type = AccessCase::CustomGetter;
+
+            newCase = AccessCase::get(
+                vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy,
+                slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
+                slot.isCacheableCustom() ? slot.slotBase() : nullptr);
+        }
     }
 
-    MacroAssemblerCodePtr codePtr = stubInfo.addAccessCase(
-        vm, codeBlock, propertyName, WTF::move(newCase));
+    MacroAssemblerCodePtr codePtr =
+        stubInfo.addAccessCase(codeBlock, propertyName, WTFMove(newCase));
 
     if (!codePtr)
         return GiveUpOnCache;
@@ -373,17 +379,16 @@ static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, Str
         if (slot.type() == PutPropertySlot::ExistingProperty) {
             structure->didCachePropertyReplacement(vm, slot.cachedOffset());
         
-            ptrdiff_t offsetToPatchedStorage = offsetRelativeToPatchedStorage(slot.cachedOffset());
             if (stubInfo.cacheType == CacheType::Unset
-                && MacroAssembler::isPtrAlignedAddressOffset(offsetToPatchedStorage)
+                && isInlineOffset(slot.cachedOffset())
+                && MacroAssembler::isPtrAlignedAddressOffset(maxOffsetRelativeToBase(slot.cachedOffset()))
                 && !structure->needImpurePropertyWatchpoint()
                 && !structure->inferredTypeFor(ident.impl())) {
 
                 repatchByIdSelfAccess(
                     codeBlock, stubInfo, structure, slot.cachedOffset(),
                     appropriateOptimizingPutByIdFunction(slot, putKind), false);
-                stubInfo.initPutByIdReplace(
-                    vm, codeBlock, structure, slot.cachedOffset());
+                stubInfo.initPutByIdReplace(codeBlock, structure, slot.cachedOffset());
                 return RetryCacheLater;
             }
 
@@ -450,8 +455,7 @@ static InlineCacheAction tryCachePutByID(ExecState* exec, JSValue baseValue, Str
         }
     }
 
-    MacroAssemblerCodePtr codePtr = stubInfo.addAccessCase(
-        vm, codeBlock, ident, WTF::move(newCase));
+    MacroAssemblerCodePtr codePtr = stubInfo.addAccessCase(codeBlock, ident, WTFMove(newCase));
     
     if (!codePtr)
         return GiveUpOnCache;
@@ -480,7 +484,7 @@ static InlineCacheAction tryRepatchIn(
     if (forceICFailure(exec))
         return GiveUpOnCache;
     
-    if (!base->structure()->propertyAccessesAreCacheable())
+    if (!base->structure()->propertyAccessesAreCacheable() || (!wasFound && !base->structure()->propertyAccessesAreCacheableForAbsence()))
         return GiveUpOnCache;
     
     if (wasFound) {
@@ -508,7 +512,7 @@ static InlineCacheAction tryRepatchIn(
     std::unique_ptr<AccessCase> newCase = AccessCase::in(
         vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, structure, conditionSet);
 
-    MacroAssemblerCodePtr codePtr = stubInfo.addAccessCase(vm, codeBlock, ident, WTF::move(newCase));
+    MacroAssemblerCodePtr codePtr = stubInfo.addAccessCase(codeBlock, ident, WTFMove(newCase));
     if (!codePtr)
         return GiveUpOnCache;
 
@@ -557,7 +561,7 @@ void linkFor(
     ASSERT(!callLinkInfo.isLinked());
     callLinkInfo.setCallee(exec->callerFrame()->vm(), callLinkInfo.hotPathBegin(), callerCodeBlock, callee);
     callLinkInfo.setLastSeenCallee(exec->callerFrame()->vm(), callerCodeBlock, callee);
-    if (shouldShowDisassemblyFor(callerCodeBlock))
+    if (shouldDumpDisassemblyFor(callerCodeBlock))
         dataLog("Linking call in ", *callerCodeBlock, " at ", callLinkInfo.codeOrigin(), " to ", pointerDump(calleeCodeBlock), ", entrypoint at ", codePtr, "\n");
     MacroAssembler::repatchNearCall(callLinkInfo.hotPathOther(), CodeLocationLabel(codePtr));
     
@@ -597,7 +601,7 @@ static void revertCall(VM* vm, CallLinkInfo& callLinkInfo, MacroAssemblerCodeRef
 
 void unlinkFor(VM& vm, CallLinkInfo& callLinkInfo)
 {
-    if (Options::showDisassembly())
+    if (Options::dumpDisassembly())
         dataLog("Unlinking call from ", callLinkInfo.callReturnLocation(), "\n");
     
     revertCall(&vm, callLinkInfo, vm.getCTIStub(linkCallThunkGenerator));
@@ -609,7 +613,7 @@ void linkVirtualFor(
     CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
     VM* vm = callerCodeBlock->vm();
 
-    if (shouldShowDisassemblyFor(callerCodeBlock))
+    if (shouldDumpDisassemblyFor(callerCodeBlock))
         dataLog("Linking virtual call at ", *callerCodeBlock, " ", exec->callerFrame()->codeOrigin(), "\n");
     
     MacroAssemblerCodeRef virtualThunk = virtualThunkFor(vm, callLinkInfo);
@@ -677,9 +681,9 @@ void linkPolymorphicCall(
             else
 #endif
                 codeBlock = jsCast<FunctionExecutable*>(executable)->codeBlockForCall();
-            // If we cannot handle a callee, assume that it's better for this whole thing to be a
-            // virtual call.
-            if (exec->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.isVarargs()) {
+            // If we cannot handle a callee, either because we don't have a CodeBlock or because arity mismatch,
+            // assume that it's better for this whole thing to be a virtual call.
+            if (!codeBlock || exec->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.isVarargs()) {
                 linkVirtualFor(exec, callLinkInfo);
                 return;
             }
@@ -795,7 +799,8 @@ void linkPolymorphicCall(
             AssemblyHelpers::selectScratchGPR(calleeGPR, comparisonValueGPR, GPRInfo::regT3);
     }
     stubJit.move(CCallHelpers::TrustedImmPtr(fastCounts.get()), fastCountsBaseGPR);
-    
+    if (!frameShuffler && callLinkInfo.isTailCall())
+        stubJit.emitRestoreCalleeSaves();
     BinarySwitch binarySwitch(comparisonValueGPR, caseValues, BinarySwitch::IntPtr);
     CCallHelpers::JumpList done;
     while (binarySwitch.advance(stubJit)) {
@@ -816,7 +821,6 @@ void linkPolymorphicCall(
             CallFrameShuffler(stubJit, frameShuffler->snapshot()).prepareForTailCall();
             calls[caseIndex].call = stubJit.nearTailCall();
         } else if (callLinkInfo.isTailCall()) {
-            stubJit.emitRestoreCalleeSaves();
             stubJit.prepareForTailCallSlow();
             calls[caseIndex].call = stubJit.nearTailCall();
         } else
@@ -874,7 +878,7 @@ void linkPolymorphicCall(
                 toCString(*callerCodeBlock).data(), callLinkInfo.callReturnLocation().labelAtOffset(0).executableAddress(),
                 toCString(listDump(callCases)).data())),
         *vm, callerCodeBlock, exec->callerFrame(), callLinkInfo, callCases,
-        WTF::move(fastCounts)));
+        WTFMove(fastCounts)));
     
     MacroAssembler::replaceWithJump(
         MacroAssembler::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()),