Changeset 62896 in webkit
- Timestamp:
- Jul 8, 2010 10:47:49 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r62885 r62896 1 2010-07-08 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Sam Weinig. 4 5 Property declarations in an object literal should not consider the prototype chain when being added to the new object 6 https://bugs.webkit.org/show_bug.cgi?id=41929 7 8 To fix this all we need to do is ensure that all new properties are 9 added with putDirect rather than a fully generic call to put. This 10 is safe as an object literal is by definition going to produce a 11 completely normal object. 12 13 Rather than duplicating all the put_by_id logic we add an additional 14 flag to op_put_by_id to indicate it should be using putDirect. In 15 the interpreter this adds a runtime branch, but in the jit this is 16 essentially free as the branch is taken at compile time. This does 17 actually improve object literal creation time even in the interpreter 18 as we no longer need to walk the prototype chain to verify that the 19 cached put is safe. 20 21 We still emit normal put_by_id code when emitting __proto__ as we want 22 to get the correct handling for changing the prototype. 23 24 Sunspider claims this is a 0.7% speedup which is conceivably real due 25 to the performance improvement in object literals, but I suspect its 26 really just the result of code motion. 27 28 * bytecode/Opcode.h: 29 * bytecompiler/BytecodeGenerator.cpp: 30 (JSC::BytecodeGenerator::emitPutById): 31 (JSC::BytecodeGenerator::emitDirectPutById): 32 * bytecompiler/BytecodeGenerator.h: 33 * bytecompiler/NodesCodegen.cpp: 34 (JSC::PropertyListNode::emitBytecode): 35 * interpreter/Interpreter.cpp: 36 (JSC::Interpreter::privateExecute): 37 * jit/JIT.h: 38 (JSC::JIT::compilePutByIdTransition): 39 * jit/JITPropertyAccess.cpp: 40 (JSC::JIT::emit_op_put_by_id): 41 (JSC::JIT::emitSlow_op_put_by_id): 42 (JSC::JIT::privateCompilePutByIdTransition): 43 (JSC::JIT::patchPutByIdReplace): 44 * jit/JITPropertyAccess32_64.cpp: 45 (JSC::JIT::emitSlow_op_put_by_id): 46 (JSC::JIT::privateCompilePutByIdTransition): 47 (JSC::JIT::patchPutByIdReplace): 48 * jit/JITStubs.cpp: 49 (JSC::JITThunks::tryCachePutByID): 50 (JSC::DEFINE_STUB_FUNCTION): 51 * jit/JITStubs.h: 52 (JSC::): 53 * runtime/JSGlobalData.cpp: 54 (JSC::JSGlobalData::JSGlobalData): 55 * runtime/JSObject.h: 56 (JSC::JSObject::putDirect): 57 (JSC::JSValue::putDirect): 58 * runtime/JSValue.h: 59 1 60 2010-07-08 Gavin Barraclough <barraclough@apple.com> 2 61 -
trunk/JavaScriptCore/bytecode/Opcode.h
r61474 r62896 121 121 macro(op_get_array_length, 8) \ 122 122 macro(op_get_string_length, 8) \ 123 macro(op_put_by_id, 8) \124 macro(op_put_by_id_transition, 8) \125 macro(op_put_by_id_replace, 8) \126 macro(op_put_by_id_generic, 8) \123 macro(op_put_by_id, 9) \ 124 macro(op_put_by_id_transition, 9) \ 125 macro(op_put_by_id_replace, 9) \ 126 macro(op_put_by_id_generic, 9) \ 127 127 macro(op_del_by_id, 4) \ 128 128 macro(op_get_by_val, 4) \ -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r61430 r62896 1281 1281 instructions().append(0); 1282 1282 instructions().append(0); 1283 instructions().append(0); 1284 return value; 1285 } 1286 1287 RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value) 1288 { 1289 #if ENABLE(JIT) 1290 m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id)); 1291 #else 1292 m_codeBlock->addPropertyAccessInstruction(instructions().size()); 1293 #endif 1294 1295 emitOpcode(op_put_by_id); 1296 instructions().append(base->index()); 1297 instructions().append(addConstant(property)); 1298 instructions().append(value->index()); 1299 instructions().append(0); 1300 instructions().append(0); 1301 instructions().append(0); 1302 instructions().append(0); 1303 instructions().append(property != m_globalData->propertyNames->underscoreProto); 1283 1304 return value; 1284 1305 } -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r61430 r62896 329 329 RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property); 330 330 RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value); 331 RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value); 331 332 RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&); 332 333 RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property); -
trunk/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r61623 r62896 267 267 switch (p->m_node->m_type) { 268 268 case PropertyNode::Constant: { 269 generator.emit PutById(newObj.get(), p->m_node->name(), value);269 generator.emitDirectPutById(newObj.get(), p->m_node->name(), value); 270 270 break; 271 271 } -
trunk/JavaScriptCore/interpreter/Interpreter.cpp
r62766 r62896 2903 2903 } 2904 2904 DEFINE_OPCODE(op_put_by_id) { 2905 /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) 2905 /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b) 2906 2906 2907 2907 Generic property access: Sets the property named by identifier … … 2910 2910 Unlike many opcodes, this one does not write any output to 2911 2911 the register file. 2912 2913 The "direct" flag should only be set this put_by_id is to initialize 2914 an object literal. 2912 2915 */ 2913 2916 … … 2915 2918 int property = vPC[2].u.operand; 2916 2919 int value = vPC[3].u.operand; 2920 int direct = vPC[8].u.operand; 2917 2921 2918 2922 JSValue baseValue = callFrame->r(base).jsValue(); 2919 2923 Identifier& ident = codeBlock->identifier(property); 2920 2924 PutPropertySlot slot; 2921 baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); 2925 if (direct) { 2926 baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot); 2927 ASSERT(slot.base() == baseValue); 2928 } else 2929 baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); 2922 2930 CHECK_FOR_EXCEPTION(); 2923 2931 … … 2928 2936 } 2929 2937 DEFINE_OPCODE(op_put_by_id_transition) { 2930 /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) 2938 /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b) 2931 2939 2932 2940 Cached property access: Attempts to set a new property with a cached transition … … 2949 2957 ASSERT(baseCell->isObject()); 2950 2958 JSObject* baseObject = asObject(baseCell); 2951 2952 RefPtr<Structure>* it = vPC[6].u.structureChain->head(); 2953 2954 JSValue proto = baseObject->structure()->prototypeForLookup(callFrame); 2955 while (!proto.isNull()) { 2956 if (UNLIKELY(asObject(proto)->structure() != (*it).get())) { 2957 uncachePutByID(codeBlock, vPC); 2958 NEXT_INSTRUCTION(); 2959 int direct = vPC[8].u.operand; 2960 2961 if (direct) { 2962 RefPtr<Structure>* it = vPC[6].u.structureChain->head(); 2963 2964 JSValue proto = baseObject->structure()->prototypeForLookup(callFrame); 2965 while (!proto.isNull()) { 2966 if (UNLIKELY(asObject(proto)->structure() != (*it).get())) { 2967 uncachePutByID(codeBlock, vPC); 2968 NEXT_INSTRUCTION(); 2969 } 2970 ++it; 2971 proto = asObject(proto)->structure()->prototypeForLookup(callFrame); 2959 2972 } 2960 ++it;2961 proto = asObject(proto)->structure()->prototypeForLookup(callFrame);2962 2973 } 2963 2964 2974 baseObject->transitionTo(newStructure); 2965 2975 … … 2978 2988 } 2979 2989 DEFINE_OPCODE(op_put_by_id_replace) { 2980 /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n) 2990 /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n) direct(b) 2981 2991 2982 2992 Cached property access: Attempts to set a pre-existing, cached … … 3013 3023 } 3014 3024 DEFINE_OPCODE(op_put_by_id_generic) { 3015 /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) 3025 /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b) 3016 3026 3017 3027 Generic property access: Sets the property named by identifier … … 3024 3034 int property = vPC[2].u.operand; 3025 3035 int value = vPC[3].u.operand; 3036 int direct = vPC[8].u.operand; 3026 3037 3027 3038 JSValue baseValue = callFrame->r(base).jsValue(); 3028 3039 Identifier& ident = codeBlock->identifier(property); 3029 3040 PutPropertySlot slot; 3030 baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); 3041 if (direct) { 3042 baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot); 3043 ASSERT(slot.base() == baseValue); 3044 } else 3045 baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); 3031 3046 CHECK_FOR_EXCEPTION(); 3032 3047 -
trunk/JavaScriptCore/jit/JIT.h
r60376 r62896 212 212 } 213 213 214 static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress )214 static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct) 215 215 { 216 216 JIT jit(globalData, codeBlock); 217 jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress );217 jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress, direct); 218 218 } 219 219 … … 231 231 232 232 static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress); 233 static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress );233 static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct); 234 234 static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr); 235 235 … … 267 267 void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame); 268 268 void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame); 269 void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress );269 void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress, bool direct); 270 270 271 271 void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, TrampolineStructure *trampolines); -
trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
r59955 r62896 308 308 Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand)); 309 309 unsigned valueVReg = currentInstruction[3].u.operand; 310 unsigned direct = currentInstruction[8].u.operand; 310 311 311 312 emitGetVirtualRegisters(baseVReg, regT0, valueVReg, regT1); 312 313 313 JITStubCall stubCall(this, cti_op_put_by_id_generic);314 JITStubCall stubCall(this, direct ? cti_op_put_by_id_direct_generic, cti_op_put_by_id_generic); 314 315 stubCall.addArgument(regT0); 315 316 stubCall.addArgument(ImmPtr(ident)); … … 531 532 unsigned baseVReg = currentInstruction[1].u.operand; 532 533 Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand)); 534 unsigned direct = currentInstruction[8].u.operand; 533 535 534 536 unsigned propertyAccessInstructionIndex = m_propertyAccessInstructionIndex++; … … 537 539 linkSlowCase(iter); 538 540 539 JITStubCall stubCall(this, cti_op_put_by_id);541 JITStubCall stubCall(this, direct ? cti_op_put_by_id_direct : cti_op_put_by_id); 540 542 stubCall.addArgument(regT0); 541 543 stubCall.addArgument(ImmPtr(ident)); … … 591 593 } 592 594 593 void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress )595 void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct) 594 596 { 595 597 JumpList failureCases; … … 600 602 601 603 // ecx = baseObject->m_structure 602 for (RefPtr<Structure>* it = chain->head(); *it; ++it) 603 testPrototype(it->get(), failureCases); 604 if (!direct) { 605 for (RefPtr<Structure>* it = chain->head(); *it; ++it) 606 testPrototype(it->get(), failureCases); 607 } 604 608 605 609 Call callTarget; … … 642 646 LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); 643 647 644 patchBuffer.link(failureCall, FunctionPtr( cti_op_put_by_id_fail));648 patchBuffer.link(failureCall, FunctionPtr(direct ? cti_op_put_by_id_direct_fail : cti_op_put_by_id_fail)); 645 649 646 650 if (willNeedStorageRealloc) { … … 695 699 } 696 700 697 void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress )701 void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct) 698 702 { 699 703 RepatchBuffer repatchBuffer(codeBlock); … … 701 705 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 702 706 // Should probably go to cti_op_put_by_id_fail, but that doesn't do anything interesting right now. 703 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr( cti_op_put_by_id_generic));707 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic)); 704 708 705 709 int offset = sizeof(JSValue) * cachedOffset; -
trunk/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r61830 r62896 532 532 int base = currentInstruction[1].u.operand; 533 533 int ident = currentInstruction[2].u.operand; 534 534 int direct = currentInstruction[8].u.operand; 535 535 536 linkSlowCaseIfNotJSCell(iter, base); 536 537 linkSlowCase(iter); 537 538 538 JITStubCall stubCall(this, cti_op_put_by_id);539 JITStubCall stubCall(this, direct ? cti_op_put_by_id_direct : cti_op_put_by_id); 539 540 stubCall.addArgument(regT1, regT0); 540 541 stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident)))); … … 593 594 } 594 595 595 void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress )596 void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct) 596 597 { 597 598 // It is assumed that regT0 contains the basePayload and regT1 contains the baseTag. The value can be found on the stack. … … 602 603 testPrototype(oldStructure, failureCases); 603 604 604 // Verify that nothing in the prototype chain has a setter for this property. 605 for (RefPtr<Structure>* it = chain->head(); *it; ++it) 606 testPrototype(it->get(), failureCases); 607 605 if (!direct) { 606 // Verify that nothing in the prototype chain has a setter for this property. 607 for (RefPtr<Structure>* it = chain->head(); *it; ++it) 608 testPrototype(it->get(), failureCases); 609 } 610 608 611 // Reallocate property storage if needed. 609 612 Call callTarget; … … 644 647 LinkBuffer patchBuffer(this, m_codeBlock->executablePool()); 645 648 646 patchBuffer.link(failureCall, FunctionPtr( cti_op_put_by_id_fail));649 patchBuffer.link(failureCall, FunctionPtr(direct ? cti_op_put_by_id_direct_fail : cti_op_put_by_id_fail)); 647 650 648 651 if (willNeedStorageRealloc) { … … 698 701 } 699 702 700 void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress )703 void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct) 701 704 { 702 705 RepatchBuffer repatchBuffer(codeBlock); … … 704 707 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 705 708 // Should probably go to cti_op_put_by_id_fail, but that doesn't do anything interesting right now. 706 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr( cti_op_put_by_id_generic));709 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic)); 707 710 708 711 int offset = sizeof(JSValue) * cachedOffset; -
trunk/JavaScriptCore/jit/JITStubs.cpp
r62432 r62896 845 845 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) 846 846 847 NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo )847 NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo, bool direct) 848 848 { 849 849 // The interpreter checks for recursion here; I do not believe this can occur in CTI. … … 854 854 // Uncacheable: give up. 855 855 if (!slot.isCacheable()) { 856 ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr( cti_op_put_by_id_generic));856 ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic)); 857 857 return; 858 858 } … … 862 862 863 863 if (structure->isUncacheableDictionary()) { 864 ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr( cti_op_put_by_id_generic));864 ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic)); 865 865 return; 866 866 } … … 868 868 // If baseCell != base, then baseCell must be a proxy for another object. 869 869 if (baseCell != slot.base()) { 870 ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr( cti_op_put_by_id_generic));870 ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic)); 871 871 return; 872 872 } … … 877 877 if (slot.type() == PutPropertySlot::NewProperty) { 878 878 if (structure->isDictionary()) { 879 ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr( cti_op_put_by_id_generic));879 ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic)); 880 880 return; 881 881 } … … 886 886 StructureChain* prototypeChain = structure->prototypeChain(callFrame); 887 887 stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain); 888 JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress );888 JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct); 889 889 return; 890 890 } … … 892 892 stubInfo->initPutByIdReplace(structure); 893 893 894 JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress );894 JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress, direct); 895 895 } 896 896 … … 1345 1345 } 1346 1346 1347 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_generic) 1348 { 1349 STUB_INIT_STACK_FRAME(stackFrame); 1350 1351 PutPropertySlot slot; 1352 stackFrame.args[0].jsValue().putDirect(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot); 1353 CHECK_FOR_EXCEPTION_AT_END(); 1354 } 1355 1347 1356 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_generic) 1348 1357 { … … 1367 1376 CallFrame* callFrame = stackFrame.callFrame; 1368 1377 Identifier& ident = stackFrame.args[1].identifier(); 1369 1378 1370 1379 PutPropertySlot slot; 1371 1380 stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot); 1372 1381 1373 1382 CodeBlock* codeBlock = stackFrame.callFrame->codeBlock(); 1374 1383 StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS); … … 1376 1385 stubInfo->setSeen(); 1377 1386 else 1378 JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo); 1379 1387 JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false); 1388 1389 CHECK_FOR_EXCEPTION_AT_END(); 1390 } 1391 1392 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct) 1393 { 1394 STUB_INIT_STACK_FRAME(stackFrame); 1395 CallFrame* callFrame = stackFrame.callFrame; 1396 Identifier& ident = stackFrame.args[1].identifier(); 1397 1398 PutPropertySlot slot; 1399 stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot); 1400 1401 CodeBlock* codeBlock = stackFrame.callFrame->codeBlock(); 1402 StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS); 1403 if (!stubInfo->seenOnce()) 1404 stubInfo->setSeen(); 1405 else 1406 JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true); 1407 1380 1408 CHECK_FOR_EXCEPTION_AT_END(); 1381 1409 } … … 1391 1419 stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot); 1392 1420 1421 CHECK_FOR_EXCEPTION_AT_END(); 1422 } 1423 1424 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_fail) 1425 { 1426 STUB_INIT_STACK_FRAME(stackFrame); 1427 1428 CallFrame* callFrame = stackFrame.callFrame; 1429 Identifier& ident = stackFrame.args[1].identifier(); 1430 1431 PutPropertySlot slot; 1432 stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot); 1433 1393 1434 CHECK_FOR_EXCEPTION_AT_END(); 1394 1435 } -
trunk/JavaScriptCore/jit/JITStubs.h
r60631 r62896 258 258 259 259 static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&, StructureStubInfo* stubInfo); 260 static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo );260 static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo, bool direct); 261 261 262 262 MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_trampolineStructure.ctiStringLengthTrampoline; } … … 379 379 void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION); 380 380 void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION); 381 void JIT_STUB cti_op_put_by_id_direct(STUB_ARGS_DECLARATION); 382 void JIT_STUB cti_op_put_by_id_direct_fail(STUB_ARGS_DECLARATION); 383 void JIT_STUB cti_op_put_by_id_direct_generic(STUB_ARGS_DECLARATION); 381 384 void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION); 382 385 void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION); -
trunk/JavaScriptCore/runtime/JSObject.h
r60762 r62896 178 178 void putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); 179 179 void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0); 180 void putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&); 180 181 181 182 void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr = 0); … … 591 592 } 592 593 594 inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 595 { 596 putDirectInternal(propertyName, value, 0, false, slot, 0); 597 } 598 593 599 inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) 594 600 { … … 693 699 } 694 700 701 inline void JSValue::putDirect(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 702 { 703 ASSERT(isCell() && isObject()); 704 asObject(asCell())->putDirect(propertyName, value, slot); 705 } 706 695 707 inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value) 696 708 { -
trunk/JavaScriptCore/runtime/JSValue.h
r60631 r62896 182 182 JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const; 183 183 void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 184 void putDirect(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); 184 185 void put(ExecState*, unsigned propertyName, JSValue); 185 186 -
trunk/LayoutTests/ChangeLog
r62894 r62896 1 2010-07-08 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Sam Weinig. 4 5 Property declarations in an object literal should not consider the prototype chain when being added to the new object 6 https://bugs.webkit.org/show_bug.cgi?id=41929 7 8 Add tests to ensure correct behaviour of object literals when there 9 are setters on the prototype chain. 10 11 * fast/js/object-literal-direct-put-expected.txt: Added. 12 * fast/js/object-literal-direct-put.html: Added. 13 * fast/js/script-tests/object-literal-direct-put.js: Added. 14 * ietestcenter/Javascript/15.4.4.14-9-b-i-6-expected.txt: 15 * ietestcenter/Javascript/15.4.4.15-8-b-i-6-expected.txt: 16 * platform/chromium/test_expectations.txt: 17 1 18 2010-07-08 Simon Fraser <simon.fraser@apple.com> 2 19 -
trunk/LayoutTests/ietestcenter/Javascript/15.4.4.14-9-b-i-6-expected.txt
r62810 r62896 5 5 6 6 PASS ES5Harness.preconditionPassed is true 7 FAIL ES5Harness.testPassed should be true. Was false. 7 PASS ES5Harness.testPassed is true 8 8 PASS successfullyParsed is true 9 9 -
trunk/LayoutTests/ietestcenter/Javascript/15.4.4.15-8-b-i-6-expected.txt
r62810 r62896 5 5 6 6 PASS ES5Harness.preconditionPassed is true 7 FAIL ES5Harness.testPassed should be true. Was false. 7 PASS ES5Harness.testPassed is true 8 8 PASS successfullyParsed is true 9 9 -
trunk/LayoutTests/platform/chromium/test_expectations.txt
r62870 r62896 3005 3005 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.4.4.14-4-9.html = TEXT 3006 3006 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.4.4.14-9-a-12.html = TEXT 3007 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.4.4.14-9-b-i-6.html = TEXT 3007 3008 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.4.4.15-3-12.html = TEXT 3008 3009 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.4.4.15-3-13.html = TEXT … … 3020 3021 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.4.4.15-8-9.html = TEXT 3021 3022 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.4.4.15-8-a-12.html = TEXT 3023 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.4.4.15-8-b-i-6.html = TEXT 3022 3024 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.5.4.20-4-10.html = TEXT 3023 3025 BUGAWONG WIN LINUX MAC : ietestcenter/Javascript/15.5.4.20-4-18.html = TEXT … … 3046 3048 // Likely from r62862. Probably just needs rebaseline. 3047 3049 BUGAWONG WIN LINUX MAC : fast/js/no-semi-insertion-at-end-of-script.html = TEXT 3050 BUGAWONG WIN LINUX MAC : fast/js/object-literal-direct-put.html = TEXT
Note: See TracChangeset
for help on using the changeset viewer.