Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (114182 => 114183)
--- trunk/Source/_javascript_Core/ChangeLog 2012-04-13 23:44:05 UTC (rev 114182)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-04-13 23:44:25 UTC (rev 114183)
@@ -1,5 +1,26 @@
2012-04-13 Gavin Barraclough <barraclo...@apple.com>
+ Don't rely on fixed offsets to patch method checks
+ https://bugs.webkit.org/show_bug.cgi?id=83958
+
+ Reviewed by Oliver Hunt.
+
+ * bytecode/StructureStubInfo.h:
+ - Add fields for the method check info.
+ * jit/JIT.cpp:
+ (JSC::PropertyStubCompilationInfo::copyToStubInfo):
+ - Store the offsets on the stub info, instead of asserting.
+ * jit/JIT.h:
+ - Delete all the method check related offsets.
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::patchMethodCallProto):
+ - Use the offset from the stubInfo.
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ - Pass the stubInfo to patchMethodCallProto.
+
+2012-04-13 Gavin Barraclough <barraclo...@apple.com>
+
Don't rely on fixed offsets to patch get_by_id/put_by_id
https://bugs.webkit.org/show_bug.cgi?id=83924
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (114182 => 114183)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2012-04-13 23:44:05 UTC (rev 114182)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2012-04-13 23:44:25 UTC (rev 114183)
@@ -235,7 +235,9 @@
#endif
} put;
} u;
-
+ int16_t methodCheckProtoObj;
+ int16_t methodCheckProtoStructureToCompare;
+ int16_t methodCheckPutFunction;
} baseline;
} patch;
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (114182 => 114183)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2012-04-13 23:44:05 UTC (rev 114182)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2012-04-13 23:44:25 UTC (rev 114183)
@@ -525,11 +525,13 @@
info.hotPathBegin = linkBuffer.locationOf(hotPathBegin);
switch (m_type) {
- case MethodCheck:
- ASSERT_JIT_OFFSET(MacroAssembler::differenceBetween(methodCheckStructureToCompare, methodCheckProtoObj), JIT::patchOffsetMethodCheckProtoObj);
- ASSERT_JIT_OFFSET(MacroAssembler::differenceBetween(methodCheckStructureToCompare, methodCheckProtoStructureToCompare), JIT::patchOffsetMethodCheckProtoStruct);
- ASSERT_JIT_OFFSET(MacroAssembler::differenceBetween(methodCheckStructureToCompare, methodCheckPutFunction), JIT::patchOffsetMethodCheckPutFunction);
+ case MethodCheck: {
+ CodeLocationDataLabelPtr structureToCompareLocation = linkBuffer.locationOf(methodCheckStructureToCompare);
+ info.patch.baseline.methodCheckProtoObj = MacroAssembler::differenceBetweenCodePtr(structureToCompareLocation, linkBuffer.locationOf(methodCheckProtoObj));
+ info.patch.baseline.methodCheckProtoStructureToCompare = MacroAssembler::differenceBetweenCodePtr(structureToCompareLocation, linkBuffer.locationOf(methodCheckProtoStructureToCompare));
+ info.patch.baseline.methodCheckPutFunction = MacroAssembler::differenceBetweenCodePtr(structureToCompareLocation, linkBuffer.locationOf(methodCheckPutFunction));
// No break - fall through to GetById.
+ }
case GetById: {
CodeLocationLabel hotPathBeginLocation = linkBuffer.locationOf(hotPathBegin);
info.patch.baseline.u.get.structureToCompare = MacroAssembler::differenceBetweenCodePtr(hotPathBeginLocation, linkBuffer.locationOf(getStructureToCompare));
Modified: trunk/Source/_javascript_Core/jit/JIT.h (114182 => 114183)
--- trunk/Source/_javascript_Core/jit/JIT.h 2012-04-13 23:44:05 UTC (rev 114182)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2012-04-13 23:44:25 UTC (rev 114183)
@@ -360,7 +360,7 @@
static void resetPatchPutById(RepatchBuffer&, StructureStubInfo*);
static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct);
- static void patchMethodCallProto(JSGlobalData&, CodeBlock* codeblock, MethodCallLinkInfo&, JSObject*, Structure*, JSObject*, ReturnAddressPtr);
+ static void patchMethodCallProto(JSGlobalData&, CodeBlock* codeblock, MethodCallLinkInfo&, StructureStubInfo&, JSObject*, Structure*, JSObject*, ReturnAddressPtr);
static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
{
@@ -481,17 +481,9 @@
#if CPU(X86)
static const int patchOffsetOpCallCompareToJump = 6;
-
- static const int patchOffsetMethodCheckProtoObj = 11;
- static const int patchOffsetMethodCheckProtoStruct = 18;
- static const int patchOffsetMethodCheckPutFunction = 29;
#elif CPU(ARM_TRADITIONAL)
static const int patchOffsetOpCallCompareToJump = 12;
- static const int patchOffsetMethodCheckProtoObj = 12;
- static const int patchOffsetMethodCheckProtoStruct = 20;
- static const int patchOffsetMethodCheckPutFunction = 32;
-
// sequenceOpCall
static const int sequenceOpCallInstructionSpace = 12;
static const int sequenceOpCallConstantSpace = 2;
@@ -509,37 +501,11 @@
static const int sequencePutByIdConstantSpace = 4;
#elif CPU(ARM_THUMB2)
static const int patchOffsetOpCallCompareToJump = 16;
-
- static const int patchOffsetMethodCheckProtoObj = 24;
- static const int patchOffsetMethodCheckProtoStruct = 34;
- static const int patchOffsetMethodCheckPutFunction = 58;
-
- // sequenceOpCall
- static const int sequenceOpCallInstructionSpace = 12;
- static const int sequenceOpCallConstantSpace = 2;
- // sequenceMethodCheck
- static const int sequenceMethodCheckInstructionSpace = 40;
- static const int sequenceMethodCheckConstantSpace = 6;
- // sequenceGetByIdHotPath
- static const int sequenceGetByIdHotPathInstructionSpace = 36;
- static const int sequenceGetByIdHotPathConstantSpace = 4;
- // sequenceGetByIdSlowCase
- static const int sequenceGetByIdSlowCaseInstructionSpace = 40;
- static const int sequenceGetByIdSlowCaseConstantSpace = 2;
- // sequencePutById
- static const int sequencePutByIdInstructionSpace = 36;
- static const int sequencePutByIdConstantSpace = 4;
#elif CPU(MIPS)
#if WTF_MIPS_ISA(1)
static const int patchOffsetOpCallCompareToJump = 32;
- static const int patchOffsetMethodCheckProtoObj = 32;
- static const int patchOffsetMethodCheckProtoStruct = 56;
- static const int patchOffsetMethodCheckPutFunction = 88;
#else // WTF_MIPS_ISA(1)
static const int patchOffsetOpCallCompareToJump = 32;
- static const int patchOffsetMethodCheckProtoObj = 32;
- static const int patchOffsetMethodCheckProtoStruct = 52;
- static const int patchOffsetMethodCheckPutFunction = 84;
#endif
#elif CPU(SH4)
// sequenceOpCall
@@ -559,10 +525,6 @@
static const int sequencePutByIdConstantSpace = 5;
static const int patchOffsetOpCallCompareToJump = 4;
-
- static const int patchOffsetMethodCheckProtoObj = 12;
- static const int patchOffsetMethodCheckProtoStruct = 20;
- static const int patchOffsetMethodCheckPutFunction = 32;
#else
#error "JSVALUE32_64 not supported on this platform."
#endif
@@ -609,10 +571,6 @@
#if CPU(X86_64)
static const int patchOffsetOpCallCompareToJump = 9;
-
- static const int patchOffsetMethodCheckProtoObj = 20;
- static const int patchOffsetMethodCheckProtoStruct = 30;
- static const int patchOffsetMethodCheckPutFunction = 50;
#endif
#endif // USE(JSVALUE32_64)
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (114182 => 114183)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2012-04-13 23:44:05 UTC (rev 114182)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2012-04-13 23:44:25 UTC (rev 114183)
@@ -1119,7 +1119,7 @@
failureCases.append(branchPtr(NotEqual, Address(regT3, JSCell::structureOffset()), TrustedImmPtr(prototype.asCell()->structure())));
}
-void JIT::patchMethodCallProto(JSGlobalData& globalData, CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSObject* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress)
+void JIT::patchMethodCallProto(JSGlobalData& globalData, CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, StructureStubInfo& stubInfo, JSObject* callee, Structure* structure, JSObject* proto, ReturnAddressPtr returnAddress)
{
RepatchBuffer repatchBuffer(codeBlock);
@@ -1127,9 +1127,9 @@
methodCallLinkInfo.cachedStructure.set(globalData, structureLocation, codeBlock->ownerExecutable(), structure);
Structure* prototypeStructure = proto->structure();
- methodCallLinkInfo.cachedPrototypeStructure.set(globalData, structureLocation.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoStruct), codeBlock->ownerExecutable(), prototypeStructure);
- methodCallLinkInfo.cachedPrototype.set(globalData, structureLocation.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoObj), codeBlock->ownerExecutable(), proto);
- methodCallLinkInfo.cachedFunction.set(globalData, structureLocation.dataLabelPtrAtOffset(patchOffsetMethodCheckPutFunction), codeBlock->ownerExecutable(), callee);
+ methodCallLinkInfo.cachedPrototypeStructure.set(globalData, structureLocation.dataLabelPtrAtOffset(stubInfo.patch.baseline.methodCheckProtoStructureToCompare), codeBlock->ownerExecutable(), prototypeStructure);
+ methodCallLinkInfo.cachedPrototype.set(globalData, structureLocation.dataLabelPtrAtOffset(stubInfo.patch.baseline.methodCheckProtoObj), codeBlock->ownerExecutable(), proto);
+ methodCallLinkInfo.cachedFunction.set(globalData, structureLocation.dataLabelPtrAtOffset(stubInfo.patch.baseline.methodCheckPutFunction), codeBlock->ownerExecutable(), callee);
repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_method_check_update));
}
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (114182 => 114183)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-04-13 23:44:05 UTC (rev 114182)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2012-04-13 23:44:25 UTC (rev 114183)
@@ -1517,6 +1517,7 @@
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
+ StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
if (!methodCallLinkInfo.seenOnce()) {
methodCallLinkInfo.setSeen();
@@ -1555,7 +1556,7 @@
// Check to see if the function is on the object's prototype. Patch up the code to optimize.
if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
- JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
@@ -1566,7 +1567,7 @@
// for now. For now it performs a check on a special object on the global object only used for this
// purpose. The object is in no way exposed, and as such the check will always pass.
if (slot.slotBase() == baseValue) {
- JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
}
@@ -1590,6 +1591,7 @@
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
+ StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
ASSERT(methodCallLinkInfo.seenOnce());
@@ -1650,7 +1652,7 @@
// Check to see if the function is on the object's prototype. Patch up the code to optimize.
if (slot.slotBase() == proto) {
- JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
@@ -1661,7 +1663,7 @@
// useful. We could try to nop it out altogether, but that's a little messy, so lets do something simpler
// for now. For now it performs a check on a special object on the global object only used for this
// purpose. The object is in no way exposed, and as such the check will always pass.
- JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}