Changeset 116670 in webkit
- Timestamp:
- May 10, 2012 11:40:29 AM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r116659 r116670 1 2012-05-10 Gavin Barraclough <barraclough@apple.com> 2 3 Cache inheritorID on JSFunction 4 https://bugs.webkit.org/show_bug.cgi?id=85853 5 6 Reviewed by Geoff Garen & Filip Pizlo. 7 8 An object's prototype is indicated via its structure. To create an otherwise 9 empty object with object A as its prototype, we require a structure with its 10 prototype set to point to A. We wish to use this same structure for all empty 11 objects created with a prototype of A, so we presently store this structure as 12 a property of A, known as the inheritorID. 13 14 When a function F is invoked as a constructor, where F has a property 'prototype' 15 set to point to A, in order to create the 'this' value for the constructor to 16 use the following steps are taken: 17 - the 'prototype' proptery of F is read, via a regular [[Get]] access. 18 - the inheritorID internal property of the prototype is read. 19 - a new, empty object is constructed with its structure set to point to inheritorID. 20 21 There are two drawbacks to the current approach: 22 - it requires that every object has an inheritorID field. 23 - it requires a [[Get]] access on every constructor call to access the 'prototype' property. 24 25 Instead, switch to caching a copy of the inheritorID on the function. Constructor 26 calls now only need read the internal property from the callee, saving a [[Get]]. 27 This also means that JSObject::m_inheritorID is no longer commonly read, and in a 28 future patch we can move to storing this in a more memory efficient fashion. 29 30 * JavaScriptCore.xcodeproj/project.pbxproj: 31 * bytecode/CodeBlock.cpp: 32 (JSC::CodeBlock::dump): 33 * bytecode/Opcode.h: 34 (JSC): 35 (JSC::padOpcodeName): 36 * bytecompiler/BytecodeGenerator.cpp: 37 (JSC::BytecodeGenerator::BytecodeGenerator): 38 * dfg/DFGAbstractState.cpp: 39 (JSC::DFG::AbstractState::execute): 40 * dfg/DFGByteCodeParser.cpp: 41 (JSC::DFG::ByteCodeParser::parseBlock): 42 * dfg/DFGNodeType.h: 43 (DFG): 44 * dfg/DFGOperations.cpp: 45 * dfg/DFGOperations.h: 46 * dfg/DFGPredictionPropagationPhase.cpp: 47 (JSC::DFG::PredictionPropagationPhase::propagate): 48 * dfg/DFGSpeculativeJIT32_64.cpp: 49 (JSC::DFG::SpeculativeJIT::compile): 50 * dfg/DFGSpeculativeJIT64.cpp: 51 (JSC::DFG::SpeculativeJIT::compile): 52 * interpreter/Interpreter.cpp: 53 (JSC::Interpreter::privateExecute): 54 * jit/JITInlineMethods.h: 55 (JSC::JIT::emitAllocateJSFunction): 56 * jit/JITOpcodes.cpp: 57 (JSC::JIT::emit_op_create_this): 58 (JSC::JIT::emitSlow_op_create_this): 59 * jit/JITOpcodes32_64.cpp: 60 (JSC::JIT::emit_op_create_this): 61 (JSC::JIT::emitSlow_op_create_this): 62 * jit/JITStubs.cpp: 63 (JSC::DEFINE_STUB_FUNCTION): 64 * llint/LLIntSlowPaths.cpp: 65 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 66 * llint/LowLevelInterpreter32_64.asm: 67 * llint/LowLevelInterpreter64.asm: 68 * runtime/JSFunction.cpp: 69 (JSC::JSFunction::JSFunction): 70 (JSC::JSFunction::cacheInheritorID): 71 (JSC): 72 (JSC::JSFunction::put): 73 (JSC::JSFunction::defineOwnProperty): 74 * runtime/JSFunction.h: 75 (JSC::JSFunction::cachedInheritorID): 76 (JSFunction): 77 (JSC::JSFunction::offsetOfCachedInheritorID): 78 1 79 2012-05-10 Michael Saboff <msaboff@apple.com> 2 80 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r115590 r116670 1042 1042 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedTranscendentalFunction.h; sourceTree = "<group>"; }; 1043 1043 869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; }; 1044 86A054461556451B00445157 /* LowLevelInterpreter.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter.asm; path = llint/LowLevelInterpreter.asm; sourceTree = "<group>"; }; 1045 86A054471556451B00445157 /* LowLevelInterpreter32_64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter32_64.asm; path = llint/LowLevelInterpreter32_64.asm; sourceTree = "<group>"; }; 1046 86A054481556451B00445157 /* LowLevelInterpreter64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter64.asm; path = llint/LowLevelInterpreter64.asm; sourceTree = "<group>"; }; 1044 1047 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; }; 1045 1048 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; }; … … 1431 1434 A767FF9F14F4502900789059 /* JSCTypedArrayStubs.h */, 1432 1435 F68EBB8C0255D4C601FF60F7 /* config.h */, 1433 0F46809C14BA7F4D00BFE272 /* llint */,1434 1436 1432EBD70A34CAD400717B9F /* API */, 1435 1437 9688CB120ED12B4E001D649F /* assembler */, … … 1441 1443 1429D77A0ED20D7300B89619 /* interpreter */, 1442 1444 1429D92C0ED22D7000B89619 /* jit */, 1445 0F46809C14BA7F4D00BFE272 /* llint */, 1443 1446 7E39D8370EC3A388003AF11A /* parser */, 1444 1447 95AB831A0DA42C6900BC83F3 /* profiler */, … … 1490 1493 0F4680A014BA7F8200BFE272 /* LLIntSlowPaths.h */, 1491 1494 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */, 1495 86A054461556451B00445157 /* LowLevelInterpreter.asm */, 1496 86A054471556451B00445157 /* LowLevelInterpreter32_64.asm */, 1497 86A054481556451B00445157 /* LowLevelInterpreter64.asm */, 1492 1498 ); 1493 1499 name = llint; -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r113648 r116670 520 520 case op_create_this: { 521 521 int r0 = (++it)->u.operand; 522 int r1 = (++it)->u.operand; 523 dataLog("[%4d] create_this %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); 522 dataLog("[%4d] create_this %s\n", location, registerName(exec, r0).data()); 524 523 break; 525 524 } -
trunk/Source/JavaScriptCore/bytecode/Opcode.h
r113136 r116670 43 43 macro(op_init_lazy_reg, 2) \ 44 44 macro(op_create_arguments, 2) \ 45 macro(op_create_this, 3) \45 macro(op_create_this, 2) \ 46 46 macro(op_get_callee, 2) \ 47 47 macro(op_convert_this, 2) \ -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r113363 r116670 443 443 444 444 if (isConstructor()) { 445 RefPtr<RegisterID> func = newTemporary();446 RefPtr<RegisterID> funcProto = newTemporary();447 448 emitOpcode(op_get_callee);449 instructions().append(func->index());450 // Load prototype.451 emitGetById(funcProto.get(), func.get(), globalData()->propertyNames->prototype);452 453 445 emitOpcode(op_create_this); 454 446 instructions().append(m_thisRegister.index()); 455 instructions().append(funcProto->index());456 447 } else if (!codeBlock->isStrictMode() && (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks)) { 457 448 emitOpcode(op_convert_this); -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r115248 r116670 775 775 break; 776 776 } 777 777 778 778 case CreateThis: { 779 Node& child = m_graph[node.child1()];780 779 AbstractValue& source = forNode(node.child1()); 781 780 AbstractValue& destination = forNode(nodeIndex); 782 781 783 if (child.shouldSpeculateFinalObject()) 784 source.filter(PredictFinalObject); 785 782 source.filter(PredictFunction); 786 783 destination.set(PredictFinalObject); 787 784 break; 788 785 } 789 786 790 787 case NewObject: 791 788 forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->emptyObjectStructure()); -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r116168 r116670 1535 1535 1536 1536 case op_create_this: { 1537 NodeIndex op1 = get(currentInstruction[2].u.operand); 1538 set(currentInstruction[1].u.operand, addToGraph(CreateThis, op1)); 1537 if (m_inlineStackTop->m_inlineCallFrame) 1538 set(currentInstruction[1].u.operand, addToGraph(CreateThis, getDirect(m_inlineStackTop->m_calleeVR))); 1539 else 1540 set(currentInstruction[1].u.operand, addToGraph(CreateThis, addToGraph(GetCallee))); 1539 1541 NEXT_OPCODE(op_create_this); 1540 1542 } -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r115867 r116670 210 210 } 211 211 212 inline JSCell* createThis(ExecState* exec, JSCell* prototype, JSFunction* constructor) 213 { 212 JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSCell* constructor) 213 { 214 JSGlobalData* globalData = &exec->globalData(); 215 NativeCallFrameTracer tracer(globalData, exec); 216 214 217 #if !ASSERT_DISABLED 215 218 ConstructData constructData; 216 ASSERT( constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);219 ASSERT(jsCast<JSFunction*>(constructor)->methodTable()->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS); 217 220 #endif 218 221 219 JSGlobalData& globalData = exec->globalData(); 220 NativeCallFrameTracer tracer(&globalData, exec); 221 222 Structure* structure; 223 if (prototype->isObject()) 224 structure = asObject(prototype)->inheritorID(globalData); 225 else 226 structure = constructor->scope()->globalObject->emptyObjectStructure(); 227 228 return constructEmptyObject(exec, structure); 229 } 230 231 JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSCell* prototype) 232 { 233 JSGlobalData* globalData = &exec->globalData(); 234 NativeCallFrameTracer tracer(globalData, exec); 235 236 return createThis(exec, prototype, jsCast<JSFunction*>(exec->callee())); 237 } 238 239 JSCell* DFG_OPERATION operationCreateThisInlined(ExecState* exec, JSCell* prototype, JSCell* constructor) 240 { 241 JSGlobalData* globalData = &exec->globalData(); 242 NativeCallFrameTracer tracer(globalData, exec); 243 244 return createThis(exec, prototype, jsCast<JSFunction*>(constructor)); 222 return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->cachedInheritorID(exec)); 245 223 } 246 224 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r113930 r116670 98 98 // These routines are provide callbacks out to C++ implementations of operations too complex to JIT. 99 99 JSCell* DFG_OPERATION operationNewObject(ExecState*); 100 JSCell* DFG_OPERATION operationCreateThis(ExecState*, JSCell* encodedOp1); 101 JSCell* DFG_OPERATION operationCreateThisInlined(ExecState*, JSCell* encodedOp1, JSCell* constructor); 100 JSCell* DFG_OPERATION operationCreateThis(ExecState*, JSCell* constructor); 102 101 EncodedJSValue DFG_OPERATION operationConvertThis(ExecState*, EncodedJSValue encodedOp1); 103 102 EncodedJSValue DFG_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r115248 r116670 3030 3030 // otherwise we'd start taking slow path a lot). 3031 3031 3032 SpeculateCellOperand proto(this, node.child1());3032 SpeculateCellOperand callee(this, node.child1()); 3033 3033 GPRTemporary result(this); 3034 3034 GPRTemporary scratch(this); 3035 3035 3036 GPRReg protoGPR = proto.gpr();3036 GPRReg calleeGPR = callee.gpr(); 3037 3037 GPRReg resultGPR = result.gpr(); 3038 3038 GPRReg scratchGPR = scratch.gpr(); 3039 3039 3040 proto.use();3041 3040 // Load the inheritorID. If the inheritorID is not set, go to slow path. 3041 m_jit.loadPtr(MacroAssembler::Address(calleeGPR, JSFunction::offsetOfCachedInheritorID()), scratchGPR); 3042 3042 MacroAssembler::JumpList slowPath; 3043 3044 // Need to verify that the prototype is an object. If we have reason to believe3045 // that it's a FinalObject then we speculate on that directly. Otherwise we3046 // do the slow (structure-based) check.3047 if (at(node.child1()).shouldSpeculateFinalObject()) {3048 if (!isFinalObjectPrediction(m_state.forNode(node.child1()).m_type))3049 speculationCheck(BadType, JSValueSource::unboxedCell(protoGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSFinalObject::s_info)));3050 } else {3051 m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSCell::structureOffset()), scratchGPR);3052 slowPath.append(m_jit.branch8(MacroAssembler::Below, MacroAssembler::Address(scratchGPR, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType)));3053 }3054 3055 // Load the inheritorID (the Structure that objects who have protoGPR as the prototype3056 // use to refer to that prototype). If the inheritorID is not set, go to slow path.3057 m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSObject::offsetOfInheritorID()), scratchGPR);3058 3043 slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, scratchGPR)); 3059 3044 … … 3065 3050 3066 3051 silentSpillAllRegisters(resultGPR); 3067 if (node.codeOrigin.inlineCallFrame) 3068 callOperation(operationCreateThisInlined, resultGPR, protoGPR, node.codeOrigin.inlineCallFrame->callee.get()); 3069 else 3070 callOperation(operationCreateThis, resultGPR, protoGPR); 3052 callOperation(operationCreateThis, resultGPR, calleeGPR); 3071 3053 silentFillAllRegisters(resultGPR); 3072 3054 3073 3055 done.link(&m_jit); 3074 3056 3075 cellResult(resultGPR, m_compileIndex , UseChildrenCalledExplicitly);3057 cellResult(resultGPR, m_compileIndex); 3076 3058 break; 3077 3059 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r115248 r116670 3054 3054 // otherwise we'd start taking slow path a lot). 3055 3055 3056 SpeculateCellOperand proto(this, node.child1());3056 SpeculateCellOperand callee(this, node.child1()); 3057 3057 GPRTemporary result(this); 3058 3058 GPRTemporary scratch(this); 3059 3059 3060 GPRReg protoGPR = proto.gpr();3060 GPRReg calleeGPR = callee.gpr(); 3061 3061 GPRReg resultGPR = result.gpr(); 3062 3062 GPRReg scratchGPR = scratch.gpr(); 3063 3063 3064 proto.use();3065 3064 // Load the inheritorID. If the inheritorID is not set, go to slow path. 3065 m_jit.loadPtr(MacroAssembler::Address(calleeGPR, JSFunction::offsetOfCachedInheritorID()), scratchGPR); 3066 3066 MacroAssembler::JumpList slowPath; 3067 3068 // Need to verify that the prototype is an object. If we have reason to believe3069 // that it's a FinalObject then we speculate on that directly. Otherwise we3070 // do the slow (structure-based) check.3071 if (at(node.child1()).shouldSpeculateFinalObject()) {3072 if (!isFinalObjectPrediction(m_state.forNode(node.child1()).m_type))3073 speculationCheck(BadType, JSValueRegs(protoGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSFinalObject::s_info)));3074 } else {3075 m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSCell::structureOffset()), scratchGPR);3076 slowPath.append(m_jit.branch8(MacroAssembler::Below, MacroAssembler::Address(scratchGPR, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType)));3077 }3078 3079 // Load the inheritorID (the Structure that objects who have protoGPR as the prototype3080 // use to refer to that prototype). If the inheritorID is not set, go to slow path.3081 m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSObject::offsetOfInheritorID()), scratchGPR);3082 3067 slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, scratchGPR)); 3083 3068 … … 3089 3074 3090 3075 silentSpillAllRegisters(resultGPR); 3091 if (node.codeOrigin.inlineCallFrame) 3092 callOperation(operationCreateThisInlined, resultGPR, protoGPR, node.codeOrigin.inlineCallFrame->callee.get()); 3093 else 3094 callOperation(operationCreateThis, resultGPR, protoGPR); 3076 callOperation(operationCreateThis, resultGPR, calleeGPR); 3095 3077 silentFillAllRegisters(resultGPR); 3096 3078 3097 3079 done.link(&m_jit); 3098 3080 3099 cellResult(resultGPR, m_compileIndex , UseChildrenCalledExplicitly);3081 cellResult(resultGPR, m_compileIndex); 3100 3082 break; 3101 3083 } -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r116455 r116670 4810 4810 4811 4811 int thisRegister = vPC[1].u.operand; 4812 int protoRegister = vPC[2].u.operand;4813 4812 4814 4813 JSFunction* constructor = jsCast<JSFunction*>(callFrame->callee()); … … 4818 4817 #endif 4819 4818 4820 Structure* structure; 4821 JSValue proto = callFrame->r(protoRegister).jsValue(); 4822 if (proto.isObject()) 4823 structure = asObject(proto)->inheritorID(callFrame->globalData()); 4824 else 4825 structure = constructor->scope()->globalObject->emptyObjectStructure(); 4819 Structure* structure = constructor->cachedInheritorID(callFrame); 4826 4820 callFrame->uncheckedR(thisRegister) = constructEmptyObject(callFrame, structure); 4827 4821 -
trunk/Source/JavaScriptCore/jit/JITInlineMethods.h
r115141 r116670 449 449 storePtr(TrustedImmPtr(executable), Address(result, JSFunction::offsetOfExecutable())); 450 450 451 // clear the function's inheritorID 452 storePtr(TrustedImmPtr(0), Address(result, JSFunction::offsetOfCachedInheritorID())); 453 451 454 // store the function's name 452 455 ASSERT(executable->nameValue()); -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r115096 r116670 1273 1273 void JIT::emit_op_create_this(Instruction* currentInstruction) 1274 1274 { 1275 emitGetVirtualRegister(currentInstruction[2].u.operand, regT2); 1276 emitJumpSlowCaseIfNotJSCell(regT2, currentInstruction[2].u.operand); 1277 loadPtr(Address(regT2, JSCell::structureOffset()), regT1); 1278 addSlowCase(emitJumpIfNotObject(regT1)); 1279 1280 // now we know that the prototype is an object, but we don't know if it's got an 1281 // inheritor ID 1282 1283 loadPtr(Address(regT2, JSObject::offsetOfInheritorID()), regT2); 1275 emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT0); 1276 loadPtr(Address(regT0, JSFunction::offsetOfCachedInheritorID()), regT2); 1284 1277 addSlowCase(branchTestPtr(Zero, regT2)); 1285 1278 … … 1288 1281 1289 1282 emitAllocateJSFinalObject(regT2, regT0, regT1); 1290 1291 1283 emitPutVirtualRegister(currentInstruction[1].u.operand); 1292 1284 } … … 1294 1286 void JIT::emitSlow_op_create_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1295 1287 { 1296 linkSlowCaseIfNotJSCell(iter, currentInstruction[2].u.operand); // not a cell1297 linkSlowCase(iter); // not an object1298 1288 linkSlowCase(iter); // doesn't have an inheritor ID 1299 1289 linkSlowCase(iter); // allocation failed 1300 1290 JITStubCall stubCall(this, cti_op_create_this); 1301 stubCall.addArgument(currentInstruction[2].u.operand, regT1);1302 1291 stubCall.call(currentInstruction[1].u.operand); 1303 1292 } -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r114702 r116670 1533 1533 void JIT::emit_op_create_this(Instruction* currentInstruction) 1534 1534 { 1535 emitLoad(currentInstruction[2].u.operand, regT1, regT0); 1536 emitJumpSlowCaseIfNotJSCell(currentInstruction[2].u.operand, regT1); 1537 loadPtr(Address(regT0, JSCell::structureOffset()), regT1); 1538 addSlowCase(emitJumpIfNotObject(regT1)); 1539 1540 // now we know that the prototype is an object, but we don't know if it's got an 1541 // inheritor ID 1542 1543 loadPtr(Address(regT0, JSObject::offsetOfInheritorID()), regT2); 1535 emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT0); 1536 loadPtr(Address(regT0, JSFunction::offsetOfCachedInheritorID()), regT2); 1544 1537 addSlowCase(branchTestPtr(Zero, regT2)); 1545 1538 … … 1548 1541 1549 1542 emitAllocateJSFinalObject(regT2, regT0, regT1); 1550 1551 1543 emitStoreCell(currentInstruction[1].u.operand, regT0); 1552 1544 } … … 1554 1546 void JIT::emitSlow_op_create_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1555 1547 { 1556 linkSlowCaseIfNotJSCell(iter, currentInstruction[2].u.operand); // not a cell1557 linkSlowCase(iter); // not an object1558 1548 linkSlowCase(iter); // doesn't have an inheritor ID 1559 1549 linkSlowCase(iter); // allocation failed 1560 unsigned protoRegister = currentInstruction[2].u.operand;1561 emitLoad(protoRegister, regT1, regT0);1562 1550 JITStubCall stubCall(this, cti_op_create_this); 1563 stubCall.addArgument(regT1, regT0);1564 1551 stubCall.call(currentInstruction[1].u.operand); 1565 1552 } -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r116494 r116670 1287 1287 #endif 1288 1288 1289 Structure* structure; 1290 JSValue proto = stackFrame.args[0].jsValue(); 1291 if (proto.isObject()) 1292 structure = asObject(proto)->inheritorID(*stackFrame.globalData); 1293 else 1294 structure = constructor->scope()->globalObject->emptyObjectStructure(); 1289 Structure* structure = constructor->cachedInheritorID(callFrame); 1295 1290 JSValue result = constructEmptyObject(callFrame, structure); 1296 1291 -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r116363 r116670 459 459 #endif 460 460 461 Structure* structure; 462 JSValue proto = LLINT_OP(2).jsValue(); 463 if (proto.isObject()) 464 structure = asObject(proto)->inheritorID(globalData); 465 else 466 structure = constructor->scope()->globalObject->emptyObjectStructure(); 467 461 Structure* structure = constructor->cachedInheritorID(exec); 468 462 LLINT_RETURN(constructEmptyObject(exec, structure)); 469 463 } -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r116361 r116670 344 344 _llint_op_create_this: 345 345 traceExecution() 346 loadi 8[PC], t0 347 assertNotConstant(t0) 348 bineq TagOffset[cfr, t0, 8], CellTag, .opCreateThisSlow 349 loadi PayloadOffset[cfr, t0, 8], t0 350 loadp JSCell::m_structure[t0], t1 351 bbb Structure::m_typeInfo + TypeInfo::m_type[t1], ObjectType, .opCreateThisSlow 352 loadp JSObject::m_inheritorID[t0], t2 346 loadp Callee[cfr], t0 347 loadp JSFunction::m_cachedInheritorID[t0], t2 353 348 btpz t2, .opCreateThisSlow 354 349 allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t2, t0, t1, t3, .opCreateThisSlow) … … 356 351 storei CellTag, TagOffset[cfr, t1, 8] 357 352 storei t0, PayloadOffset[cfr, t1, 8] 358 dispatch( 3)353 dispatch(2) 359 354 360 355 .opCreateThisSlow: 361 356 callSlowPath(_llint_slow_path_create_this) 362 dispatch( 3)357 dispatch(2) 363 358 364 359 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r116361 r116670 222 222 _llint_op_create_this: 223 223 traceExecution() 224 loadis 16[PB, PC, 8], t0 225 assertNotConstant(t0) 226 loadp [cfr, t0, 8], t0 227 btpnz t0, tagMask, .opCreateThisSlow 228 loadp JSCell::m_structure[t0], t1 229 bbb Structure::m_typeInfo + TypeInfo::m_type[t1], ObjectType, .opCreateThisSlow 230 loadp JSObject::m_inheritorID[t0], t2 224 loadp Callee[cfr], t0 225 loadp JSFunction::m_cachedInheritorID[t0], t2 231 226 btpz t2, .opCreateThisSlow 232 227 allocateBasicJSObject(JSFinalObjectSizeClassIndex, JSGlobalData::jsFinalObjectClassInfo, t2, t0, t1, t3, .opCreateThisSlow) 233 228 loadis 8[PB, PC, 8], t1 234 229 storep t0, [cfr, t1, 8] 235 dispatch( 3)230 dispatch(2) 236 231 237 232 .opCreateThisSlow: 238 233 callSlowPath(_llint_slow_path_create_this) 239 dispatch( 3)234 dispatch(2) 240 235 241 236 -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r112285 r116670 113 113 } 114 114 115 Structure* JSFunction::cacheInheritorID(ExecState* exec) 116 { 117 JSValue prototype = get(exec, exec->globalData().propertyNames->prototype); 118 if (prototype.isObject()) 119 m_cachedInheritorID.set(exec->globalData(), this, asObject(prototype)->inheritorID(exec->globalData())); 120 else 121 m_cachedInheritorID.set(exec->globalData(), this, globalObject()->emptyObjectStructure()); 122 return m_cachedInheritorID.get(); 123 } 124 115 125 const UString& JSFunction::name(ExecState* exec) 116 126 { … … 333 343 PropertySlot slot; 334 344 thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot); 345 thisObject->m_cachedInheritorID.clear(); 335 346 } 336 347 if (thisObject->jsExecutable()->isStrictMode() && (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller)) { … … 373 384 PropertySlot slot; 374 385 thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot); 386 thisObject->m_cachedInheritorID.clear(); 375 387 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); 376 388 } -
trunk/Source/JavaScriptCore/runtime/JSFunction.h
r111739 r116670 122 122 } 123 123 124 Structure* cachedInheritorID(ExecState* exec) 125 { 126 if (UNLIKELY(!m_cachedInheritorID)) 127 return cacheInheritorID(exec); 128 return m_cachedInheritorID.get(); 129 } 130 131 static size_t offsetOfCachedInheritorID() 132 { 133 return OBJECT_OFFSETOF(JSFunction, m_cachedInheritorID); 134 } 135 124 136 protected: 125 137 const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; … … 130 142 void finishCreation(ExecState*, NativeExecutable*, int length, const Identifier& name); 131 143 void finishCreation(ExecState*, FunctionExecutable*, ScopeChainNode*); 144 145 Structure* cacheInheritorID(ExecState*); 132 146 133 147 static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&); … … 153 167 WriteBarrier<ExecutableBase> m_executable; 154 168 WriteBarrier<ScopeChainNode> m_scopeChain; 169 WriteBarrier<Structure> m_cachedInheritorID; 155 170 }; 156 171
Note: See TracChangeset
for help on using the changeset viewer.