Changeset 202627 in webkit
- Timestamp:
- Jun 29, 2016 9:53:25 AM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r202611 r202627 1 2016-06-29 Caio Lima <ticaiolima@gmail.com> 2 3 LLInt should support other types of prototype GetById caching. 4 https://bugs.webkit.org/show_bug.cgi?id=158083 5 6 Recently, we started supporting prototype load caching for get_by_id 7 in the LLInt. This patch is expading the caching strategy to enable 8 cache the prototype accessor and custom acessors. 9 10 Similarly to the get_by_id_proto_load bytecode, we are adding new 11 bytecodes called get_by_id_proto_accessor that uses the calculated 12 offset of a object to call a getter function and get_by_id_proto_custom 13 that stores the pointer to the custom function and call them directly 14 from LowLevelInterpreter. 15 16 Reviewed by Keith Miller 17 18 * bytecode/BytecodeList.json: 19 * bytecode/BytecodeUseDef.h: 20 (JSC::computeUsesForBytecodeOffset): 21 (JSC::computeDefsForBytecodeOffset): 22 * bytecode/CodeBlock.cpp: 23 (JSC::CodeBlock::printGetByIdOp): 24 (JSC::CodeBlock::dumpBytecode): 25 (JSC::CodeBlock::finalizeLLIntInlineCaches): 26 * bytecode/GetByIdStatus.cpp: 27 (JSC::GetByIdStatus::computeFromLLInt): 28 * dfg/DFGByteCodeParser.cpp: 29 (JSC::DFG::ByteCodeParser::parseBlock): 30 * dfg/DFGCapabilities.cpp: 31 (JSC::DFG::capabilityLevel): 32 * jit/JIT.cpp: 33 (JSC::JIT::privateCompileMainPass): 34 (JSC::JIT::privateCompileSlowCases): 35 * llint/LLIntSlowPaths.cpp: 36 (JSC::LLInt::setupGetByIdPrototypeCache): 37 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 38 * llint/LLIntSlowPaths.h: 39 * llint/LowLevelInterpreter32_64.asm: 40 * llint/LowLevelInterpreter64.asm: 41 1 42 2016-06-28 Commit Queue <commit-queue@webkit.org> 2 43 -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.json
r202435 r202627 65 65 { "name" : "op_get_by_id_proto_load", "length" : 9 }, 66 66 { "name" : "op_get_by_id_unset", "length" : 9 }, 67 { "name" : "op_get_by_id_proto_accessor", "length" : 9 }, 68 { "name" : "op_get_by_id_proto_custom", "length" : 9 }, 67 69 { "name" : "op_get_by_id_with_this", "length" : 5 }, 68 70 { "name" : "op_get_by_val_with_this", "length" : 5 }, -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r202125 r202627 165 165 case op_get_by_id_proto_load: 166 166 case op_get_by_id_unset: 167 case op_get_by_id_proto_accessor: 168 case op_get_by_id_proto_custom: 167 169 case op_get_array_length: 168 170 case op_typeof: … … 404 406 case op_get_by_id_proto_load: 405 407 case op_get_by_id_unset: 408 case op_get_by_id_proto_accessor: 409 case op_get_by_id_proto_custom: 406 410 case op_get_by_id_with_this: 407 411 case op_get_by_val_with_this: -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r202588 r202627 355 355 op = "get_by_id_unset"; 356 356 break; 357 case op_get_by_id_proto_accessor: 358 op = "op_get_by_id_proto_accessor"; 359 break; 360 case op_get_by_id_proto_custom: 361 op = "op_get_by_id_proto_custom"; 362 break; 357 363 case op_get_array_length: 358 364 op = "array_length"; … … 1138 1144 case op_get_by_id_proto_load: 1139 1145 case op_get_by_id_unset: 1146 case op_get_by_id_proto_accessor: 1147 case op_get_by_id_proto_custom: 1140 1148 case op_get_array_length: { 1141 1149 printGetByIdOp(out, exec, location, it); … … 2797 2805 case op_get_by_id: 2798 2806 case op_get_by_id_proto_load: 2799 case op_get_by_id_unset: { 2807 case op_get_by_id_unset: 2808 case op_get_by_id_proto_accessor: 2809 case op_get_by_id_proto_custom: { 2800 2810 StructureID oldStructureID = curInstruction[4].u.structureID; 2801 2811 if (!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID))) -
trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
r202093 r202627 79 79 Opcode opcode = instruction[0].u.opcode; 80 80 81 ASSERT(opcode == LLInt::getOpcode(op_get_array_length) || opcode == LLInt::getOpcode(op_try_get_by_id) || opcode == LLInt::getOpcode(op_get_by_id_proto_load) || opcode == LLInt::getOpcode(op_get_by_id) || opcode == LLInt::getOpcode(op_get_by_id_unset) );81 ASSERT(opcode == LLInt::getOpcode(op_get_array_length) || opcode == LLInt::getOpcode(op_try_get_by_id) || opcode == LLInt::getOpcode(op_get_by_id_proto_load) || opcode == LLInt::getOpcode(op_get_by_id) || opcode == LLInt::getOpcode(op_get_by_id_unset) || opcode == LLInt::getOpcode(op_get_by_id_proto_accessor) || opcode == LLInt::getOpcode(op_get_by_id_proto_custom)); 82 82 83 83 // FIXME: We should not just bail if we see a try_get_by_id or a get_by_id_proto_load. -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r202098 r202627 108 108 109 109 class UnlinkedCodeBlock : public JSCell { 110 friend class LLIntOffsetsExtractor; 110 111 public: 111 112 typedef JSCell Base; -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r202487 r202627 4146 4146 case op_get_by_id_proto_load: 4147 4147 case op_get_by_id_unset: 4148 case op_get_by_id_proto_accessor: 4149 case op_get_by_id_proto_custom: 4148 4150 case op_get_array_length: { 4149 4151 SpeculatedType prediction = getPrediction(); -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r202125 r202627 159 159 case op_get_by_id_proto_load: 160 160 case op_get_by_id_unset: 161 case op_get_by_id_proto_accessor: 162 case op_get_by_id_proto_custom: 161 163 case op_get_by_id_with_this: 162 164 case op_get_by_val_with_this: -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r202397 r202627 251 251 case op_get_by_id_proto_load: 252 252 case op_get_by_id_unset: 253 case op_get_by_id_proto_accessor: 254 case op_get_by_id_proto_custom: 253 255 DEFINE_OP(op_get_by_id) 254 256 DEFINE_OP(op_get_by_id_with_this) … … 436 438 case op_get_by_id_proto_load: 437 439 case op_get_by_id_unset: 440 case op_get_by_id_proto_accessor: 441 case op_get_by_id_proto_custom: 438 442 DEFINE_SLOWCASE_OP(op_get_by_id) 439 443 DEFINE_SLOWCASE_OP(op_get_by_val) -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r202588 r202627 599 599 if (slot.isUnset()) 600 600 conditions = generateConditionsForPropertyMiss(vm, codeBlock, exec, structure, ident.impl()); 601 else if (slot.isCustom()) 602 conditions = generateConditionsForPrototypePropertyHitCustom(vm, codeBlock, exec, structure, slot.slotBase(), ident.impl()); 601 603 else 602 604 conditions = generateConditionsForPrototypePropertyHit(vm, codeBlock, exec, structure, slot.slotBase(), ident.impl()); … … 615 617 result.iterator->value.add(condition, pc)->install(); 616 618 } 617 ASSERT((offset == invalidOffset) == slot.isUnset());619 ASSERT((offset == invalidOffset) == (slot.isUnset() || slot.isCustom())); 618 620 619 621 ConcurrentJITLocker locker(codeBlock->m_lock); … … 623 625 pc[4].u.structureID = structure->id(); 624 626 return; 625 } 626 ASSERT(slot.isValue()); 627 628 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_proto_load); 627 } else if (slot.isCustom()) { 628 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_proto_custom); 629 pc[4].u.structureID = structure->id(); 630 pc[5].u.getterFunc = slot.customGetter(); 631 pc[6].u.pointer = slot.attributes() & CustomAccessor ? 0 : slot.slotBase(); 632 return; 633 } 634 ASSERT(slot.isValue() || slot.isAccessor()); 635 636 if (slot.isAccessor()) 637 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_proto_accessor); 638 else 639 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_proto_load); 640 629 641 pc[4].u.structureID = structure->id(); 630 642 pc[5].u.operand = offset; … … 667 679 ConcurrentJITLocker locker(codeBlock->m_lock); 668 680 669 pc[4].u.structureID = structure->id(); 670 pc[5].u.operand = slot.cachedOffset(); 681 if (slot.isValue()) { 682 pc[4].u.structureID = structure->id(); 683 pc[5].u.operand = slot.cachedOffset(); 684 } 671 685 } 672 } else if (UNLIKELY(pc[7].u.operand && (slot.isValue() || slot.isUnset() ))) {686 } else if (UNLIKELY(pc[7].u.operand && (slot.isValue() || slot.isUnset() || ((slot.isAccessor() || slot.isCustom()) && (slot.slotBase() != baseValue))))) { 673 687 ASSERT(slot.slotBase() != baseValue); 674 688 … … 690 704 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result); 691 705 LLINT_END(); 706 } 707 708 LLINT_SLOW_PATH_DECL(slow_path_get_proto_accessor) 709 { 710 LLINT_BEGIN(); 711 JSValue baseValue = LLINT_OP_C(2).jsValue(); 712 PropertyOffset offset = pc[5].u.operand; 713 JSObject* slotBase = jsCast<JSObject*>(pc[6].u.jsCell.get()); 714 JSValue getterSetter = slotBase->getDirect(offset); 715 716 JSValue result = callGetter(exec, baseValue, getterSetter); 717 718 LLINT_RETURN_PROFILED(op_get_by_id, result); 692 719 } 693 720 -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r202131 r202627 74 74 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_try_get_by_id); 75 75 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id); 76 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_proto_accessor); 76 77 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_arguments_length); 77 78 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_id); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r202131 r202627 422 422 .ok: 423 423 end 424 end 425 426 macro loadIdentifier(index, dest) 427 loadp CodeBlock[cfr], t1 428 loadp CodeBlock::m_unlinkedCode[t1], t2 429 loadp UnlinkedCodeBlock::m_identifiers[t2], t1 430 move index, t2 431 mulp sizeof Identifier, t2 432 addp t2, t1 433 loadp Identifier::m_string[t1], dest 424 434 end 425 435 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r202435 r202627 1421 1421 .opGetByIdUnsetSlow: 1422 1422 callOpcodeSlowPath(_llint_slow_path_get_by_id) 1423 dispatch(9) 1424 1425 1426 _llint_op_get_by_id_proto_accessor: 1427 traceExecution() 1428 loadi 8[PC], t0 1429 loadi 16[PC], t1 1430 loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdProtoAcessorSlow) 1431 bineq JSCell::m_structureID[t3], t1, .opGetByIdProtoAcessorSlow 1432 callSlowPath(_llint_slow_path_get_proto_accessor) 1433 dispatch(9) 1434 1435 .opGetByIdProtoAcessorSlow: 1436 callSlowPath(_llint_slow_path_get_by_id) 1437 dispatch(9) 1438 1439 macro loadEncodedThisValue(baseValue, dest) 1440 loadp 24[PC], dest 1441 bineq 0, dest, .loadEncodedThisValueDone 1442 move baseValue, dest 1443 .loadEncodedThisValueDone: 1444 end 1445 1446 _llint_op_get_by_id_proto_custom: 1447 traceExecution() 1448 loadi 8[PC], t0 1449 loadi 16[PC], t1 1450 loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdProtoCustomSlow) 1451 bineq JSCell::m_structureID[t3], t1, .opGetByIdProtoCustomSlow 1452 # Setting the topCallFrame 1453 loadp Callee[cfr], t0 1454 andp MarkedBlockMask, t0, t1 1455 loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1 1456 storep cfr, VM::topCallFrame[t1] 1457 loadi 12[PC], t0 1458 loadIdentifier(t0, t2) 1459 loadEncodedThisValue(t3, t1) 1460 loadp 20[PC], t0 1461 # Inlining the GetValueFunc call 1462 push t1 # Load arg3 JSObject * 1463 push t2 # Load arg2 PropertyName 1464 move CellTag, t3 1465 if BIG_ENDIAN 1466 push t1 # Load arg1 Payload of EncodedJSValue 1467 push t3 # Load arg1 Tag of EncodedJSValue 1468 else 1469 push t3 # Load arg1 Tag of EncodedJSValue 1470 push t1 # Load arg1 Payload of EncodedJSValue 1471 end 1472 push cfr # Loading exec 1473 call t0 1474 addp 20, sp 1475 loadi 4[PC], t2 1476 storei r1, TagOffset[cfr, t2, 8] 1477 storei r0, PayloadOffset[cfr, t2, 8] 1478 valueProfile(r0, r1, 32, t2) 1479 dispatch(9) 1480 1481 .opGetByIdProtoCustomSlow: 1482 callSlowPath(_llint_slow_path_get_by_id) 1423 1483 dispatch(9) 1424 1484 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r202435 r202627 1295 1295 1296 1296 1297 _llint_op_get_by_id_proto_accessor: 1298 traceExecution() 1299 loadisFromInstruction(2, t0) 1300 loadConstantOrVariableCell(t0, t3, .opGetByIdProtoAcessorSlow) 1301 loadi JSCell::m_structureID[t3], t1 1302 loadisFromInstruction(4, t2) 1303 bineq t2, t1, .opGetByIdProtoAcessorSlow 1304 callSlowPath(_llint_slow_path_get_proto_accessor) 1305 dispatch(9) 1306 1307 .opGetByIdProtoAcessorSlow: 1308 callSlowPath(_llint_slow_path_get_by_id) 1309 dispatch(9) 1310 1311 1312 macro loadEncodedThisValue(baseValue, dest) 1313 loadpFromInstruction(6, dest) 1314 bineq 0, dest, .loadEncodedThisValueDone 1315 move baseValue, dest 1316 .loadEncodedThisValueDone: 1317 end 1318 1319 _llint_op_get_by_id_proto_custom: 1320 traceExecution() 1321 loadisFromInstruction(2, t0) 1322 loadConstantOrVariableCell(t0, t3, .opGetByIdProtoCustomSlow) 1323 loadi JSCell::m_structureID[t3], t1 1324 loadisFromInstruction(4, t2) 1325 bineq t2, t1, .opGetByIdProtoCustomSlow 1326 # Setting the topCallFrame 1327 loadp Callee[cfr], t0 1328 andp MarkedBlockMask, t0, t1 1329 loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1 1330 storep cfr, VM::topCallFrame[t1] 1331 push PC 1332 push PB 1333 loadpFromInstruction(3, t0) 1334 loadIdentifier(t0, a2) 1335 loadEncodedThisValue(t3, a1) 1336 loadpFromInstruction(5, t0) 1337 prepareStateForCCall() 1338 move cfr, a0 1339 move a1, a3 1340 cCall4(t0) 1341 restoreStateAfterCCall() 1342 pop PB 1343 pop PC 1344 loadisFromInstruction(1, t2) 1345 storeq r0, [cfr, t2, 8] 1346 valueProfile(r0, 8, t1) 1347 dispatch(9) 1348 1349 .opGetByIdProtoCustomSlow: 1350 callSlowPath(_llint_slow_path_get_by_id) 1351 dispatch(9) 1352 1353 1297 1354 _llint_op_get_array_length: 1298 1355 traceExecution() -
trunk/Source/JavaScriptCore/runtime/Identifier.h
r196785 r202627 88 88 class Identifier { 89 89 friend class Structure; 90 friend class LLIntOffsetsExtractor; 90 91 public: 91 92 Identifier() { }
Note: See TracChangeset
for help on using the changeset viewer.