Changeset 50254 in webkit for trunk/JavaScriptCore
- Timestamp:
- Oct 28, 2009, 6:25:02 PM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r50248 r50254 1 2009-10-28 Oliver Hunt <[email protected]> 2 3 Reviewed by Geoff Garen. 4 5 Improve for..in enumeration performance 6 https://bugs.webkit.org/show_bug.cgi?id=30887 7 8 Improve indexing of an object with a for..in iterator by 9 identifying cases where get_by_val is being used with a iterator 10 as the subscript and replace it with a new get_by_pname 11 bytecode. get_by_pname then optimizes lookups that directly access 12 the base object. 13 14 * bytecode/CodeBlock.cpp: 15 (JSC::CodeBlock::dump): 16 * bytecode/Opcode.h: 17 * bytecompiler/BytecodeGenerator.cpp: 18 (JSC::BytecodeGenerator::emitGetByVal): 19 * bytecompiler/BytecodeGenerator.h: 20 (JSC::BytecodeGenerator::pushOptimisedForIn): 21 (JSC::BytecodeGenerator::popOptimisedForIn): 22 * interpreter/Interpreter.cpp: 23 (JSC::Interpreter::privateExecute): 24 * jit/JIT.cpp: 25 (JSC::JIT::privateCompileMainPass): 26 (JSC::JIT::privateCompileSlowCases): 27 * jit/JIT.h: 28 * jit/JITPropertyAccess.cpp: 29 (JSC::JIT::compileGetDirectOffset): 30 (JSC::JIT::emit_op_get_by_pname): 31 (JSC::JIT::emitSlow_op_get_by_pname): 32 * parser/Nodes.cpp: 33 (JSC::ForInNode::emitBytecode): 34 * runtime/JSObject.h: 35 * runtime/JSPropertyNameIterator.cpp: 36 (JSC::JSPropertyNameIterator::create): 37 * runtime/JSPropertyNameIterator.h: 38 (JSC::JSPropertyNameIterator::getOffset): 39 (JSC::JSPropertyNameIterator::JSPropertyNameIterator): 40 * runtime/JSValue.h: 41 (JSC::JSValue::): 42 * runtime/Structure.cpp: 43 (JSC::Structure::addPropertyTransition): 44 (JSC::Structure::changePrototypeTransition): 45 (JSC::Structure::despecifyFunctionTransition): 46 (JSC::Structure::addAnonymousSlotsTransition): 47 (JSC::Structure::getterSetterTransition): 48 (JSC::Structure::toDictionaryTransition): 49 (JSC::Structure::addPropertyWithoutTransition): 50 Track the existence (or not) of non-enumerable properties. 51 * runtime/Structure.h: 52 (JSC::Structure::propertyStorageCapacity): 53 (JSC::Structure::propertyStorageSize): 54 (JSC::Structure::hasNonEnumerableProperties): 55 (JSC::Structure::hasAnonymousSlots): 56 1 57 2009-10-28 Dmitry Titov <[email protected]> 2 58 -
trunk/JavaScriptCore/bytecode/CodeBlock.cpp
r49734 r50254 825 825 break; 826 826 } 827 case op_get_by_pname: { 828 int r0 = (++it)->u.operand; 829 int r1 = (++it)->u.operand; 830 int r2 = (++it)->u.operand; 831 int r3 = (++it)->u.operand; 832 int r4 = (++it)->u.operand; 833 int r5 = (++it)->u.operand; 834 printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str(), registerName(r4).c_str(), registerName(r5).c_str()); 835 break; 836 } 827 837 case op_put_by_val: { 828 838 int r0 = (++it)->u.operand; … … 1016 1026 } 1017 1027 case op_get_pnames: { 1018 int r0 = it[0].u.operand; 1019 int r1 = it[1].u.operand; 1020 printf("[%4d] get_pnames\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str()); 1028 int r0 = it[1].u.operand; 1029 int r1 = it[2].u.operand; 1030 int r2 = it[3].u.operand; 1031 int r3 = it[4].u.operand; 1032 int offset = it[5].u.operand; 1033 printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str(), offset, location + offset); 1021 1034 it += OPCODE_LENGTH(op_get_pnames) - 1; 1022 1035 break; 1023 1036 } 1024 1037 case op_next_pname: { 1025 int dest = it[ 0].u.operand;1038 int dest = it[1].u.operand; 1026 1039 int iter = it[4].u.operand; 1027 1040 int offset = it[5].u.operand; -
trunk/JavaScriptCore/bytecode/Opcode.h
r49734 r50254 114 114 macro(op_del_by_id, 4) \ 115 115 macro(op_get_by_val, 4) \ 116 macro(op_get_by_pname, 7) \ 116 117 macro(op_put_by_val, 4) \ 117 118 macro(op_del_by_val, 4) \ -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r49734 r50254 1282 1282 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property) 1283 1283 { 1284 for (size_t i = m_forInContextStack.size(); i > 0; i--) { 1285 ForInContext& context = m_forInContextStack[i - 1]; 1286 if (context.propertyRegister == property) { 1287 emitOpcode(op_get_by_pname); 1288 instructions().append(dst->index()); 1289 instructions().append(base->index()); 1290 instructions().append(property->index()); 1291 instructions().append(context.expectedSubscriptRegister->index()); 1292 instructions().append(context.iterRegister->index()); 1293 instructions().append(context.indexRegister->index()); 1294 return dst; 1295 } 1296 } 1284 1297 emitOpcode(op_get_by_val); 1285 1298 instructions().append(dst->index()); -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r49734 r50254 62 62 }; 63 63 64 struct ForInContext { 65 RefPtr<RegisterID> expectedSubscriptRegister; 66 RefPtr<RegisterID> iterRegister; 67 RefPtr<RegisterID> indexRegister; 68 RefPtr<RegisterID> propertyRegister; 69 }; 70 64 71 class BytecodeGenerator : public FastAllocBase { 65 72 public: … … 332 339 void popFinallyContext(); 333 340 341 void pushOptimisedForIn(RegisterID* expectedBase, RegisterID* iter, RegisterID* index, RegisterID* propertyRegister) 342 { 343 ForInContext context = { expectedBase, iter, index, propertyRegister }; 344 m_forInContextStack.append(context); 345 } 346 347 void popOptimisedForIn() 348 { 349 m_forInContextStack.removeLast(); 350 } 351 334 352 LabelScope* breakTarget(const Identifier&); 335 353 LabelScope* continueTarget(const Identifier&); … … 468 486 Vector<ControlFlowContext> m_scopeContextStack; 469 487 Vector<SwitchInfo> m_switchContextStack; 488 Vector<ForInContext> m_forInContextStack; 470 489 471 490 int m_nextGlobalIndex; -
trunk/JavaScriptCore/interpreter/Interpreter.cpp
r49734 r50254 2416 2416 callFrame->r(dst) = result; 2417 2417 vPC += OPCODE_LENGTH(op_del_by_id); 2418 NEXT_INSTRUCTION(); 2419 } 2420 DEFINE_OPCODE(op_get_by_pname) { 2421 int dst = vPC[1].u.operand; 2422 int base = vPC[2].u.operand; 2423 int property = vPC[3].u.operand; 2424 int expected = vPC[4].u.operand; 2425 int iter = vPC[5].u.operand; 2426 int i = vPC[6].u.operand; 2427 2428 JSValue baseValue = callFrame->r(base).jsValue(); 2429 JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); 2430 JSValue subscript = callFrame->r(property).jsValue(); 2431 JSValue expectedSubscript = callFrame->r(expected).jsValue(); 2432 int index = callFrame->r(i).i() - 1; 2433 JSValue result; 2434 int offset = 0; 2435 if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) { 2436 callFrame->r(dst) = asObject(baseValue)->getDirectOffset(offset); 2437 vPC += OPCODE_LENGTH(op_get_by_pname); 2438 NEXT_INSTRUCTION(); 2439 } 2440 Identifier propertyName(callFrame, subscript.toString(callFrame)); 2441 result = baseValue.get(callFrame, propertyName); 2442 CHECK_FOR_EXCEPTION(); 2443 callFrame->r(dst) = result; 2444 vPC += OPCODE_LENGTH(op_get_by_pname); 2418 2445 NEXT_INSTRUCTION(); 2419 2446 } -
trunk/JavaScriptCore/jit/JIT.cpp
r49734 r50254 240 240 DEFINE_OP(op_get_by_id) 241 241 DEFINE_OP(op_get_by_val) 242 DEFINE_OP(op_get_by_pname) 242 243 DEFINE_OP(op_get_global_var) 243 244 DEFINE_OP(op_get_pnames) … … 386 387 DEFINE_SLOWCASE_OP(op_get_by_id) 387 388 DEFINE_SLOWCASE_OP(op_get_by_val) 389 DEFINE_SLOWCASE_OP(op_get_by_pname) 388 390 DEFINE_SLOWCASE_OP(op_instanceof) 389 391 DEFINE_SLOWCASE_OP(op_jfalse) -
trunk/JavaScriptCore/jit/JIT.h
r50211 r50254 429 429 void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset); 430 430 void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset); 431 void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset); 431 432 void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset); 432 433 … … 530 531 void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset); 531 532 void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset); 533 void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch); 532 534 void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset); 533 535 … … 684 686 void emit_op_get_by_id(Instruction*); 685 687 void emit_op_get_by_val(Instruction*); 688 void emit_op_get_by_pname(Instruction*); 686 689 void emit_op_get_global_var(Instruction*); 687 690 void emit_op_get_scoped_var(Instruction*); … … 773 776 void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); 774 777 void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&); 778 void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&); 775 779 void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&); 776 780 void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&); -
trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
r50201 r50254 34 34 #include "JSArray.h" 35 35 #include "JSFunction.h" 36 #include "JSPropertyNameIterator.h" 36 37 #include "Interpreter.h" 37 38 #include "LinkBuffer.h" … … 935 936 #endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) 936 937 938 void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset) 939 { 940 ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); 941 ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); 942 ASSERT(sizeof(JSValue) == 8); 943 944 Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); 945 loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); 946 loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); 947 Jump finishedLoad = jump(); 948 notUsingInlineStorage.link(this); 949 loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); 950 loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); 951 loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); 952 finishedLoad.link(this); 953 } 954 955 void JIT::emit_op_get_by_pname(Instruction* currentInstruction) 956 { 957 unsigned dst = currentInstruction[1].u.operand; 958 unsigned base = currentInstruction[2].u.operand; 959 unsigned property = currentInstruction[3].u.operand; 960 unsigned expected = currentInstruction[4].u.operand; 961 unsigned iter = currentInstruction[5].u.operand; 962 unsigned i = currentInstruction[6].u.operand; 963 964 emitLoad2(property, regT1, regT0, base, regT3, regT2); 965 emitJumpSlowCaseIfNotJSCell(property, regT1); 966 addSlowCase(branchPtr(NotEqual, regT0, payloadFor(expected))); 967 // Property registers are now available as the property is known 968 emitJumpSlowCaseIfNotJSCell(base, regT3); 969 emitLoadPayload(iter, regT1); 970 971 // Test base's structure 972 loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0); 973 addSlowCase(branchPtr(NotEqual, regT0, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))); 974 load32(addressFor(i), regT3); 975 sub32(Imm32(1), regT3); 976 addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); 977 compileGetDirectOffset(regT2, regT1, regT0, regT0, regT3); 978 979 emitStore(dst, regT1, regT0); 980 map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_pname), dst, regT1, regT0); 981 } 982 983 void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 984 { 985 unsigned dst = currentInstruction[1].u.operand; 986 unsigned base = currentInstruction[2].u.operand; 987 unsigned property = currentInstruction[3].u.operand; 988 989 linkSlowCaseIfNotJSCell(iter, property); 990 linkSlowCase(iter); 991 linkSlowCaseIfNotJSCell(iter, base); 992 linkSlowCase(iter); 993 linkSlowCase(iter); 994 995 JITStubCall stubCall(this, cti_op_get_by_val); 996 stubCall.addArgument(base); 997 stubCall.addArgument(property); 998 stubCall.call(dst); 999 } 1000 937 1001 #else // USE(JSVALUE32_64) 938 1002 … … 968 1032 } 969 1033 1034 void JIT::emit_op_get_by_pname(Instruction* currentInstruction) 1035 { 1036 unsigned dst = currentInstruction[1].u.operand; 1037 unsigned base = currentInstruction[2].u.operand; 1038 unsigned property = currentInstruction[3].u.operand; 1039 unsigned expected = currentInstruction[4].u.operand; 1040 unsigned iter = currentInstruction[5].u.operand; 1041 unsigned i = currentInstruction[6].u.operand; 1042 1043 emitGetVirtualRegister(property, regT0); 1044 addSlowCase(branchPtr(NotEqual, regT0, addressFor(expected))); 1045 emitGetVirtualRegisters(base, regT0, iter, regT1); 1046 emitJumpSlowCaseIfNotJSCell(regT0, base); 1047 1048 // Test base's structure 1049 loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2); 1050 addSlowCase(branchPtr(NotEqual, regT2, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))); 1051 load32(addressFor(i), regT3); 1052 sub32(Imm32(1), regT3); 1053 addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); 1054 compileGetDirectOffset(regT0, regT0, regT2, regT3, regT1); 1055 1056 emitPutVirtualRegister(dst, regT0); 1057 } 1058 1059 void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1060 { 1061 unsigned dst = currentInstruction[1].u.operand; 1062 unsigned base = currentInstruction[2].u.operand; 1063 unsigned property = currentInstruction[3].u.operand; 1064 1065 linkSlowCase(iter); 1066 linkSlowCaseIfNotJSCell(iter, base); 1067 linkSlowCase(iter); 1068 linkSlowCase(iter); 1069 1070 JITStubCall stubCall(this, cti_op_get_by_val); 1071 stubCall.addArgument(base, regT2); 1072 stubCall.addArgument(property, regT2); 1073 stubCall.call(dst); 1074 } 1075 970 1076 void JIT::emit_op_put_by_val(Instruction* currentInstruction) 971 1077 { … … 1350 1456 loadPtr(Address(temp, cachedOffset * sizeof(JSValue)), result); 1351 1457 } 1458 } 1459 1460 void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch) 1461 { 1462 ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); 1463 ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); 1464 1465 Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); 1466 loadPtr(BaseIndex(base, offset, ScalePtr, OBJECT_OFFSETOF(JSObject, m_inlineStorage)), result); 1467 Jump finishedLoad = jump(); 1468 notUsingInlineStorage.link(this); 1469 loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), scratch); 1470 loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result); 1471 finishedLoad.link(this); 1352 1472 } 1353 1473 -
trunk/JavaScriptCore/parser/Nodes.cpp
r49734 r50254 1478 1478 RefPtr<RegisterID> i = generator.newTemporary(); 1479 1479 RefPtr<RegisterID> size = generator.newTemporary(); 1480 RefPtr<RegisterID> expectedSubscript; 1480 1481 RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget()); 1481 1482 generator.emitJump(scope->continueTarget()); … … 1485 1486 1486 1487 RegisterID* propertyName; 1488 bool optimizedForinAccess = false; 1487 1489 if (m_lexpr->isResolveNode()) { 1488 1490 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); … … 1495 1497 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1496 1498 generator.emitPutById(base, ident, propertyName); 1499 } else { 1500 expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName); 1501 generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName); 1502 optimizedForinAccess = true; 1497 1503 } 1498 1504 } else if (m_lexpr->isDotAccessorNode()) { … … 1518 1524 1519 1525 generator.emitNode(dst, m_statement); 1526 1527 if (optimizedForinAccess) 1528 generator.popOptimisedForIn(); 1520 1529 1521 1530 generator.emitLabel(scope->continueTarget()); -
trunk/JavaScriptCore/runtime/JSObject.h
r49721 r50254 203 203 bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); } 204 204 205 static const size_tinlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3;206 static const size_tnonInlineBaseStorageCapacity = 16;205 static const unsigned inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3; 206 static const unsigned nonInlineBaseStorageCapacity = 16; 207 207 208 208 static PassRefPtr<Structure> createStructure(JSValue prototype) -
trunk/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
r49734 r50254 44 44 PropertyNameArray propertyNames(exec); 45 45 o->getPropertyNames(exec, propertyNames); 46 JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data()); 46 size_t numCacheableSlots = 0; 47 if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasAnonymousSlots() && 48 !o->structure()->isUncacheableDictionary() && !o->structure()->typeInfo().overridesGetPropertyNames()) 49 numCacheableSlots = o->structure()->propertyStorageSize(); 50 51 JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots); 47 52 48 53 if (o->structure()->isDictionary()) -
trunk/JavaScriptCore/runtime/JSPropertyNameIterator.h
r49955 r50254 55 55 virtual void markChildren(MarkStack&); 56 56 57 bool getOffset(size_t i, int& offset) 58 { 59 if (i >= m_numCacheableSlots) 60 return false; 61 offset = i; 62 return true; 63 } 64 57 65 JSValue get(ExecState*, JSObject*, size_t i); 58 66 size_t size() { return m_jsStringsSize; } … … 65 73 66 74 private: 67 JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData );75 JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot); 68 76 69 77 Structure* m_cachedStructure; 70 78 RefPtr<StructureChain> m_cachedPrototypeChain; 71 size_t m_jsStringsSize; 79 uint32_t m_numCacheableSlots; 80 uint32_t m_jsStringsSize; 72 81 OwnArrayPtr<JSValue> m_jsStrings; 73 82 }; 74 83 75 inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData )84 inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots) 76 85 : JSCell(exec->globalData().propertyNameIteratorStructure.get()) 77 86 , m_cachedStructure(0) 87 , m_numCacheableSlots(numCacheableSlots) 78 88 , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size()) 79 89 , m_jsStrings(new JSValue[m_jsStringsSize]) -
trunk/JavaScriptCore/runtime/Structure.cpp
r49734 r50254 376 376 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; 377 377 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; 378 transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; 378 379 379 380 if (structure->m_propertyTable) { … … 418 419 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; 419 420 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; 421 transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; 420 422 421 423 // Don't set m_offset, as one can not transition to this. … … 434 436 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; 435 437 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; 438 transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; 436 439 437 440 // Don't set m_offset, as one can not transition to this. … … 465 468 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; 466 469 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; 470 transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; 467 471 468 472 if (structure->m_propertyTable) { … … 493 497 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; 494 498 transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties; 499 transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; 495 500 496 501 // Don't set m_offset, as one can not transition to this. … … 511 516 transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; 512 517 transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; 518 transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; 513 519 514 520 structure->materializePropertyMapIfNecessary(); … … 551 557 552 558 m_isPinnedPropertyTable = true; 559 if (attributes & DontEnum) 560 m_hasNonEnumerableProperties = true; 561 553 562 size_t offset = put(propertyName, attributes, specificValue); 554 563 if (propertyStorageSize() > propertyStorageCapacity()) -
trunk/JavaScriptCore/runtime/Structure.h
r49734 r50254 96 96 97 97 void growPropertyStorageCapacity(); 98 size_tpropertyStorageCapacity() const { return m_propertyStorageCapacity; }99 size_tpropertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; }98 unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; } 99 unsigned propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; } 100 100 bool isUsingInlineStorage() const; 101 101 … … 120 120 void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; } 121 121 122 bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; } 123 124 bool hasAnonymousSlots() const { return m_propertyTable && m_propertyTable->anonymousSlotCount; } 125 122 126 bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; } 123 127 … … 191 195 PropertyMapHashTable* m_propertyTable; 192 196 193 size_t m_propertyStorageCapacity;197 uint32_t m_propertyStorageCapacity; 194 198 signed char m_offset; 195 199 … … 197 201 bool m_isPinnedPropertyTable : 1; 198 202 bool m_hasGetterSetterProperties : 1; 203 bool m_hasNonEnumerableProperties : 1; 199 204 #if COMPILER(WINSCW) 200 205 // Workaround for Symbian WINSCW compiler that cannot resolve unsigned type of the declared
Note:
See TracChangeset
for help on using the changeset viewer.