Ignore:
Timestamp:
Jul 30, 2009, 7:57:31 PM (16 years ago)
Author:
[email protected]
Message:

2009-07-30 Gavin Barraclough <[email protected]>

Reviewed by NOBODY (build fix).

Temporarily revert r46618 since this is b0rking on Linux.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JITStubs.cpp

    r46618 r46620  
    584584JITThunks::JITThunks(JSGlobalData* globalData)
    585585{
    586     JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk);
     586    JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallPreLink, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk);
    587587
    588588#if PLATFORM_ARM_ARCH(7)
     
    607607#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
    608608
    609 NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo)
     609NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot)
    610610{
    611611    // The interpreter checks for recursion here; I do not believe this can occur in CTI.
     
    633633        return;
    634634    }
     635
     636    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
    635637
    636638    // Cache hit: Specialize instruction and ref Structures.
     
    653655}
    654656
    655 NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo)
     657NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot)
    656658{
    657659    // FIXME: Write a test that proves we need to check for recursion here just
     
    691693        return;
    692694    }
     695
     696    // In the interpreter the last structure is trapped here; in CTI we use the
     697    // *_second method to achieve a similar (but not quite the same) effect.
     698
     699    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
    693700
    694701    // Cache hit: Specialize instruction and ref Structures.
     
    720727    size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
    721728    if (!count) {
    722         stubInfo->accessType = access_get_by_id_generic;
     729        stubInfo->opcodeID = op_get_by_id_generic;
    723730        return;
    724731    }
     
    10221029    CallFrame* callFrame = stackFrame.callFrame;
    10231030    Identifier& ident = stackFrame.args[1].identifier();
     1031
    10241032    PutPropertySlot slot;
    10251033    stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
    1026     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
    1027     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
    1028 
    1029     if (!stubInfo->seenOnce())
    1030         stubInfo->setSeen();
    1031     else
    1032         JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo);
    1033 
     1034
     1035    ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_id_second));
     1036
     1037    CHECK_FOR_EXCEPTION_AT_END();
     1038}
     1039
     1040DEFINE_STUB_FUNCTION(void, op_put_by_id_second)
     1041{
     1042    STUB_INIT_STACK_FRAME(stackFrame);
     1043
     1044    PutPropertySlot slot;
     1045    stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
     1046    JITThunks::tryCachePutByID(stackFrame.callFrame, stackFrame.callFrame->codeBlock(), STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot);
    10341047    CHECK_FOR_EXCEPTION_AT_END();
    10351048}
     
    10631076}
    10641077
    1065 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
     1078DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
    10661079{
    10671080    STUB_INIT_STACK_FRAME(stackFrame);
     
    10691082    CallFrame* callFrame = stackFrame.callFrame;
    10701083    Identifier& ident = stackFrame.args[1].identifier();
     1084
    10711085    JSValue baseValue = stackFrame.args[0].jsValue();
    10721086    PropertySlot slot(baseValue);
    10731087    JSValue result = baseValue.get(callFrame, ident, slot);
    1074     CHECK_FOR_EXCEPTION();
    1075     MethodCallLinkInfo& methodCallLinkInfo = callFrame->codeBlock()->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
    1076 
    1077     if (!methodCallLinkInfo.seenOnce())
    1078         methodCallLinkInfo.setSeen();
    1079     else {
    1080         // If we successfully got something, then the base from which it is being accessed must
    1081         // be an object.  (Assertion to ensure asObject() call below is safe, which comes after
    1082         // an isCacheable() chceck.
    1083         ASSERT(!slot.isCacheable() || slot.slotBase().isObject());
    1084 
    1085         // Check that:
    1086         //   * We're dealing with a JSCell,
    1087         //   * the property is cachable,
    1088         //   * it's not a dictionary
    1089         //   * there is a function cached.
    1090         Structure* structure;
    1091         JSCell* specific;
    1092         JSObject* slotBaseObject;
    1093         if (baseValue.isCell()
    1094             && slot.isCacheable()
    1095             && !(structure = asCell(baseValue)->structure())->isDictionary()
    1096             && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
    1097             && specific
    1098             ) {
    1099 
    1100             JSFunction* callee = (JSFunction*)specific;
    1101 
    1102             // Since we're accessing a prototype in a loop, it's a good bet that it
    1103             // should not be treated as a dictionary.
    1104             if (slotBaseObject->structure()->isDictionary())
    1105                 slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));
    1106 
    1107             // The result fetched should always be the callee!
    1108             ASSERT(result == JSValue(callee));
    1109 
    1110             // Check to see if the function is on the object's prototype.  Patch up the code to optimize.
    1111             if (slot.slotBase() == structure->prototypeForLookup(callFrame))
    1112                 JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, slotBaseObject);
    1113             // Check to see if the function is on the object itself.
    1114             // Since we generate the method-check to check both the structure and a prototype-structure (since this
    1115             // is the common case) we have a problem - we need to patch the prototype structure check to do something
    1116             // useful.  We could try to nop it out altogether, but that's a little messy, so lets do something simpler
    1117             // for now.  For now it performs a check on a special object on the global object only used for this
    1118             // purpose.  The object is in no way exposed, and as such the check will always pass.
    1119             else if (slot.slotBase() == baseValue)
    1120                 JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject()->methodCallDummy());
    1121 
    1122             // For now let any other case be cached as a normal get_by_id.
    1123         }
    1124 
    1125         // Revert the get_by_id op back to being a regular get_by_id - allow it to cache like normal, if it needs to.
    1126         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id));
    1127     }
    1128 
    1129     return JSValue::encode(result);
    1130 }
    1131 
    1132 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
     1088
     1089    ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_second));
     1090
     1091    CHECK_FOR_EXCEPTION_AT_END();
     1092    return JSValue::encode(result);
     1093}
     1094
     1095DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
    11331096{
    11341097    STUB_INIT_STACK_FRAME(stackFrame);
     
    11361099    CallFrame* callFrame = stackFrame.callFrame;
    11371100    Identifier& ident = stackFrame.args[1].identifier();
     1101
    11381102    JSValue baseValue = stackFrame.args[0].jsValue();
    11391103    PropertySlot slot(baseValue);
    11401104    JSValue result = baseValue.get(callFrame, ident, slot);
    1141     CodeBlock* codeBlock = callFrame->codeBlock();
    1142     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
    1143 
    1144     if (!stubInfo->seenOnce())
    1145         stubInfo->setSeen();
    1146     else
    1147         JITThunks::tryCacheGetByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, baseValue, ident, slot, stubInfo);
     1105
     1106    ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_method_check_second));
     1107
     1108    CHECK_FOR_EXCEPTION_AT_END();
     1109    return JSValue::encode(result);
     1110}
     1111
     1112DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_second)
     1113{
     1114    STUB_INIT_STACK_FRAME(stackFrame);
     1115
     1116    CallFrame* callFrame = stackFrame.callFrame;
     1117    Identifier& ident = stackFrame.args[1].identifier();
     1118
     1119    JSValue baseValue = stackFrame.args[0].jsValue();
     1120    PropertySlot slot(baseValue);
     1121    JSValue result = baseValue.get(callFrame, ident, slot);
     1122
     1123    CHECK_FOR_EXCEPTION();
     1124
     1125    // If we successfully got something, then the base from which it is being accessed must
     1126    // be an object.  (Assertion to ensure asObject() call below is safe, which comes after
     1127    // an isCacheable() chceck.
     1128    ASSERT(!slot.isCacheable() || slot.slotBase().isObject());
     1129
     1130    // Check that:
     1131    //   * We're dealing with a JSCell,
     1132    //   * the property is cachable,
     1133    //   * it's not a dictionary
     1134    //   * there is a function cached.
     1135    Structure* structure;
     1136    JSCell* specific;
     1137    JSObject* slotBaseObject;
     1138    if (baseValue.isCell()
     1139        && slot.isCacheable()
     1140        && !(structure = asCell(baseValue)->structure())->isDictionary()
     1141        && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
     1142        && specific
     1143        ) {
     1144
     1145        JSFunction* callee = (JSFunction*)specific;
     1146
     1147        // Since we're accessing a prototype in a loop, it's a good bet that it
     1148        // should not be treated as a dictionary.
     1149        if (slotBaseObject->structure()->isDictionary())
     1150            slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));
     1151
     1152        // The result fetched should always be the callee!
     1153        ASSERT(result == JSValue(callee));
     1154        MethodCallLinkInfo& methodCallLinkInfo = callFrame->codeBlock()->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
     1155
     1156        // Check to see if the function is on the object's prototype.  Patch up the code to optimize.
     1157        if (slot.slotBase() == structure->prototypeForLookup(callFrame))
     1158            JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, slotBaseObject);
     1159        // Check to see if the function is on the object itself.
     1160        // Since we generate the method-check to check both the structure and a prototype-structure (since this
     1161        // is the common case) we have a problem - we need to patch the prototype structure check to do something
     1162        // useful.  We could try to nop it out altogether, but that's a little messy, so lets do something simpler
     1163        // for now.  For now it performs a check on a special object on the global object only used for this
     1164        // purpose.  The object is in no way exposed, and as such the check will always pass.
     1165        else if (slot.slotBase() == baseValue)
     1166            JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject()->methodCallDummy());
     1167
     1168        // For now let any other case be cached as a normal get_by_id.
     1169    }
     1170
     1171    // Revert the get_by_id op back to being a regular get_by_id - allow it to cache like normal, if it needs to.
     1172    ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id));
     1173
     1174    return JSValue::encode(result);
     1175}
     1176
     1177DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_second)
     1178{
     1179    STUB_INIT_STACK_FRAME(stackFrame);
     1180
     1181    CallFrame* callFrame = stackFrame.callFrame;
     1182    Identifier& ident = stackFrame.args[1].identifier();
     1183
     1184    JSValue baseValue = stackFrame.args[0].jsValue();
     1185    PropertySlot slot(baseValue);
     1186    JSValue result = baseValue.get(callFrame, ident, slot);
     1187
     1188    JITThunks::tryCacheGetByID(callFrame, callFrame->codeBlock(), STUB_RETURN_ADDRESS, baseValue, ident, slot);
    11481189
    11491190    CHECK_FOR_EXCEPTION_AT_END();
     
    11771218        int listIndex = 1;
    11781219
    1179         if (stubInfo->accessType == access_get_by_id_self) {
     1220        if (stubInfo->opcodeID == op_get_by_id_self) {
    11801221            ASSERT(!stubInfo->stubRoutine);
    11811222            polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure);
     
    12011242    listIndex = 1;
    12021243
    1203     switch (stubInfo->accessType) {
    1204     case access_get_by_id_proto:
     1244    switch (stubInfo->opcodeID) {
     1245    case op_get_by_id_proto:
    12051246        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure);
    12061247        stubInfo->stubRoutine = CodeLocationLabel();
    12071248        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
    12081249        break;
    1209     case access_get_by_id_chain:
     1250    case op_get_by_id_chain:
    12101251        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
    12111252        stubInfo->stubRoutine = CodeLocationLabel();
    12121253        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
    12131254        break;
    1214     case access_get_by_id_proto_list:
     1255    case op_get_by_id_proto_list:
    12151256        prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
    12161257        listIndex = stubInfo->u.getByIdProtoList.listSize;
     
    14791520
    14801521#if ENABLE(JIT_OPTIMIZE_CALL)
    1481 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
     1522DEFINE_STUB_FUNCTION(void*, vm_dontLazyLinkCall)
    14821523{
    14831524    STUB_INIT_STACK_FRAME(stackFrame);
     
    14851526    JSGlobalData* globalData = stackFrame.globalData;
    14861527    JSFunction* callee = asFunction(stackFrame.args[0].jsValue());
     1528
     1529    ctiPatchNearCallByReturnAddress(stackFrame.callFrame->callerFrame()->codeBlock(), stackFrame.args[1].returnAddress(), globalData->jitStubs.ctiVirtualCallLink());
     1530
     1531    return callee->body()->generatedJITCode().addressForCall().executableAddress();
     1532}
     1533
     1534DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
     1535{
     1536    STUB_INIT_STACK_FRAME(stackFrame);
     1537
     1538    JSFunction* callee = asFunction(stackFrame.args[0].jsValue());
    14871539    JITCode& jitCode = callee->body()->generatedJITCode();
     1540   
     1541    CodeBlock* codeBlock = 0;
     1542    if (!callee->isHostFunction())
     1543        codeBlock = &callee->body()->bytecode(callee->scope().node());
     1544    else
     1545        codeBlock = &callee->body()->generatedBytecode();
     1546
    14881547    CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(stackFrame.args[1].returnAddress());
    1489 
    1490     if (!callLinkInfo->seenOnce())
    1491         callLinkInfo->setSeen();
    1492     else {
    1493 
    1494         CodeBlock* codeBlock = 0;
    1495         if (!callee->isHostFunction())
    1496             codeBlock = &callee->body()->bytecode(callee->scope().node());
    1497         else
    1498             codeBlock = &callee->body()->generatedBytecode();
    1499         JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, jitCode, callLinkInfo, stackFrame.args[2].int32(), globalData);
    1500 
    1501     }
     1548    JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, jitCode, callLinkInfo, stackFrame.args[2].int32(), stackFrame.globalData);
    15021549
    15031550    return jitCode.addressForCall().executableAddress();
Note: See TracChangeset for help on using the changeset viewer.