Changeset 262233 in webkit for trunk/Source/JavaScriptCore/bytecompiler
- Timestamp:
- May 27, 2020, 7:43:25 PM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore/bytecompiler
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r262165 r262233 1292 1292 m_codeBlock->addJumpTarget(instructions().size()); 1293 1293 // This disables peephole optimizations when an instruction is a jump target 1294 m_lastOpcodeID = op_end;1294 disablePeepholeOptimization(); 1295 1295 } 1296 1296 } … … 1315 1315 { 1316 1316 ASSERT(m_lastInstruction.isValid()); 1317 m_lastOpcodeID = op_end;1317 disablePeepholeOptimization(); 1318 1318 m_writer.rewind(m_lastInstruction); 1319 1319 } … … 1457 1457 { 1458 1458 OpJneqPtr::emit(this, cond, moveLinkTimeConstant(nullptr, LinkTimeConstant::applyFunction), target.bind(this)); 1459 } 1460 1461 unsigned BytecodeGenerator::emitWideJumpIfNotFunctionHasOwnProperty(RegisterID* cond, Label& target) 1462 { 1463 OpJneqPtr::emit<OpcodeSize::Wide32>(this, cond, moveLinkTimeConstant(nullptr, LinkTimeConstant::hasOwnPropertyFunction), target.bind(this)); 1464 return m_lastInstruction.offset(); 1465 } 1466 1467 void BytecodeGenerator::recordHasOwnStructurePropertyInForInLoop(StructureForInContext& structureContext, unsigned branchOffset, Label& genericPath) 1468 { 1469 RELEASE_ASSERT(genericPath.isBound()); 1470 RELEASE_ASSERT(!genericPath.isForward()); 1471 structureContext.addHasOwnPropertyJump(branchOffset, genericPath.location()); 1459 1472 } 1460 1473 … … 4329 4342 } 4330 4343 4344 RegisterID* BytecodeGenerator::emitHasOwnStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator) 4345 { 4346 OpHasOwnStructureProperty::emit(this, dst, base, propertyName, enumerator); 4347 return dst; 4348 } 4349 4331 4350 RegisterID* BytecodeGenerator::emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base) 4332 4351 { … … 4515 4534 } 4516 4535 4517 void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister )4536 void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister, RegisterID* baseRegister) 4518 4537 { 4519 4538 if (!localRegister) 4520 4539 return; 4521 4540 unsigned bodyBytecodeStartOffset = instructions().size(); 4522 m_forInContextStack.append(adoptRef(*new StructureForInContext(localRegister, indexRegister, propertyRegister, enumeratorRegister, b odyBytecodeStartOffset)));4541 m_forInContextStack.append(adoptRef(*new StructureForInContext(localRegister, indexRegister, propertyRegister, enumeratorRegister, baseRegister, bodyBytecodeStartOffset))); 4523 4542 } 4524 4543 … … 5186 5205 auto bytecode = instruction->as<OldOpType>(); 5187 5206 5188 // disable peephole optimizations 5189 generator.m_lastOpcodeID = op_end; 5207 generator.disablePeepholeOptimization(); 5190 5208 5191 5209 // Change the opcode to get_by_val. … … 5222 5240 for (const auto& instTuple : m_inInsts) 5223 5241 rewriteOp<OpInStructureProperty>(generator, instTuple); 5242 5243 for (const auto& hasOwnPropertyTuple : m_hasOwnPropertyJumpInsts) { 5244 static_assert(sizeof(OpJmp) <= sizeof(OpJneqPtr)); 5245 unsigned branchInstIndex = std::get<0>(hasOwnPropertyTuple); 5246 unsigned newBranchTarget = std::get<1>(hasOwnPropertyTuple); 5247 5248 auto instruction = generator.m_writer.ref(branchInstIndex); 5249 RELEASE_ASSERT(instruction->is<OpJneqPtr>()); 5250 RELEASE_ASSERT(instruction->isWide32()); 5251 auto end = branchInstIndex + instruction->size(); 5252 5253 generator.m_writer.seek(branchInstIndex); 5254 5255 generator.disablePeepholeOptimization(); 5256 5257 OpJmp::emit(&generator, BoundLabel(static_cast<int>(newBranchTarget) - static_cast<int>(branchInstIndex))); 5258 5259 while (generator.m_writer.position() < end) 5260 OpNop::emit<OpcodeSize::Narrow>(&generator); 5261 } 5224 5262 5225 5263 generator.m_writer.seek(generator.m_writer.size()); … … 5271 5309 } 5272 5310 5311 StructureForInContext* BytecodeGenerator::findStructureForInContext(RegisterID* property) 5312 { 5313 for (size_t i = m_forInContextStack.size(); i--; ) { 5314 ForInContext& context = m_forInContextStack[i].get(); 5315 if (context.local() != property) 5316 continue; 5317 5318 if (!context.isStructureForInContext()) 5319 break; 5320 5321 return &context.asStructureForInContext(); 5322 } 5323 5324 return nullptr; 5325 } 5326 5273 5327 } // namespace JSC 5274 5328 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r262083 r262233 240 240 using GetInst = std::tuple<unsigned, int>; 241 241 using InInst = GetInst; 242 243 StructureForInContext(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister, unsigned bodyBytecodeStartOffset) 242 using HasOwnPropertyJumpInst = std::tuple<unsigned, unsigned>; 243 244 StructureForInContext(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister, RegisterID* base, unsigned bodyBytecodeStartOffset) 244 245 : ForInContext(localRegister, Type::StructureForIn, bodyBytecodeStartOffset) 245 246 , m_indexRegister(indexRegister) 246 247 , m_propertyRegister(propertyRegister) 247 248 , m_enumeratorRegister(enumeratorRegister) 249 , m_base(base) 248 250 { 249 251 } … … 252 254 RegisterID* property() const { return m_propertyRegister.get(); } 253 255 RegisterID* enumerator() const { return m_enumeratorRegister.get(); } 256 RegisterID* base() const { return m_base.get(); } 254 257 255 258 void addGetInst(unsigned instIndex, int propertyRegIndex) … … 261 264 { 262 265 m_inInsts.append(InInst { instIndex, propertyRegIndex }); 266 } 267 268 void addHasOwnPropertyJump(unsigned branchInstIndex, unsigned genericPathTarget) 269 { 270 m_hasOwnPropertyJumpInsts.append(HasOwnPropertyJumpInst { branchInstIndex, genericPathTarget }); 263 271 } 264 272 … … 269 277 RefPtr<RegisterID> m_propertyRegister; 270 278 RefPtr<RegisterID> m_enumeratorRegister; 279 RefPtr<RegisterID> m_base; 271 280 Vector<GetInst> m_getInsts; 272 281 Vector<InInst> m_inInsts; 282 Vector<HasOwnPropertyJumpInst> m_hasOwnPropertyJumpInsts; 273 283 }; 274 284 … … 665 675 666 676 void hoistSloppyModeFunctionIfNecessary(const Identifier& functionName); 677 678 StructureForInContext* findStructureForInContext(RegisterID* property); 667 679 668 680 private: … … 871 883 void emitJumpIfNotFunctionCall(RegisterID* cond, Label& target); 872 884 void emitJumpIfNotFunctionApply(RegisterID* cond, Label& target); 885 unsigned emitWideJumpIfNotFunctionHasOwnProperty(RegisterID* cond, Label& target); 886 void recordHasOwnStructurePropertyInForInLoop(StructureForInContext&, unsigned branchOffset, Label& genericPath); 873 887 874 888 template<typename BinOp, typename JmpOp> … … 883 897 RegisterID* emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName); 884 898 RegisterID* emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator); 899 RegisterID* emitHasOwnStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator); 885 900 RegisterID* emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName); 886 901 RegisterID* emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base); … … 1011 1026 void pushIndexedForInScope(RegisterID* local, RegisterID* index); 1012 1027 void popIndexedForInScope(RegisterID* local); 1013 void pushStructureForInScope(RegisterID* local, RegisterID* index, RegisterID* property, RegisterID* enumerator );1028 void pushStructureForInScope(RegisterID* local, RegisterID* index, RegisterID* property, RegisterID* enumerator, RegisterID* base); 1014 1029 void popStructureForInScope(RegisterID* local); 1015 1030 … … 1075 1090 RegisterID* emitMove(RegisterID* dst, RegisterID* src); 1076 1091 1092 public: 1093 void disablePeepholeOptimization() { m_lastOpcodeID = op_end; } 1094 private: 1077 1095 bool canDoPeepholeOptimization() const { return m_lastOpcodeID != op_end; } 1078 1096 … … 1216 1234 auto prevLastInstruction = m_lastInstruction; 1217 1235 m_writer.swap(writer); 1218 m_lastOpcodeID = op_end;1236 disablePeepholeOptimization(); 1219 1237 m_lastInstruction = m_writer.ref(); 1220 1238 fn(); -
trunk/Source/JavaScriptCore/bytecompiler/Label.h
r252800 r262233 53 53 { } 54 54 55 explicit GenericBoundLabel(int target)55 explicit GenericBoundLabel(int offset) 56 56 : m_type(Offset) 57 57 , m_generator(nullptr) 58 , m_target( target)58 , m_target(offset) 59 59 { } 60 60 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r261895 r262233 1825 1825 generator.emitLabel(end.get()); 1826 1826 } 1827 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd()); 1828 return returnValue.get(); 1829 } 1830 1831 RegisterID* HasOwnPropertyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1832 { 1833 RefPtr<RegisterID> returnValue = generator.finalDestination(dst); 1834 RefPtr<RegisterID> base = generator.emitNode(m_base); 1835 1836 if (m_base->isOptionalChainBase()) 1837 generator.emitOptionalCheck(base.get()); 1838 1839 generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd()); 1840 1841 RefPtr<RegisterID> function = generator.emitGetById(generator.newTemporary(), base.get(), generator.propertyNames().hasOwnProperty); 1842 if (isOptionalChainBase()) 1843 generator.emitOptionalCheck(function.get()); 1844 1845 RELEASE_ASSERT(m_args->m_listNode && m_args->m_listNode->m_expr && !m_args->m_listNode->m_next); 1846 ExpressionNode* argument = m_args->m_listNode->m_expr; 1847 RELEASE_ASSERT(argument->isResolveNode()); 1848 StructureForInContext* structureContext = nullptr; 1849 Variable argumentVariable = generator.variable(static_cast<ResolveNode*>(argument)->identifier()); 1850 if (argumentVariable.isLocal()) { 1851 RegisterID* property = argumentVariable.local(); 1852 structureContext = generator.findStructureForInContext(property); 1853 } 1854 1855 if (structureContext && structureContext->base() == base.get()) { 1856 Ref<Label> realCall = generator.newLabel(); 1857 Ref<Label> end = generator.newLabel(); 1858 1859 unsigned branchInsnOffset = generator.emitWideJumpIfNotFunctionHasOwnProperty(function.get(), realCall.get()); 1860 generator.emitHasOwnStructureProperty(returnValue.get(), base.get(), generator.emitNode(argument), structureContext->enumerator()); 1861 generator.emitJump(end.get()); 1862 1863 generator.emitLabel(realCall.get()); 1864 { 1865 CallArguments callArguments(generator, m_args); 1866 generator.move(callArguments.thisRegister(), base.get()); 1867 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes); 1868 } 1869 1870 generator.emitLabel(end.get()); 1871 1872 generator.recordHasOwnStructurePropertyInForInLoop(*structureContext, branchInsnOffset, realCall); 1873 } else { 1874 CallArguments callArguments(generator, m_args); 1875 generator.move(callArguments.thisRegister(), base.get()); 1876 generator.emitCallInTailPosition(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd(), DebuggableCall::Yes); 1877 } 1878 1827 1879 generator.emitProfileType(returnValue.get(), divotStart(), divotEnd()); 1828 1880 return returnValue.get(); … … 3696 3748 generator.emitNode(generator.ignoredResult(), m_lexpr); 3697 3749 3698 RefPtr<RegisterID> base = generator.newTemporary();3699 3750 RefPtr<RegisterID> length; 3700 3751 RefPtr<RegisterID> enumerator; 3701 3752 3702 generator.emitNode(base.get(),m_expr);3753 RefPtr<RegisterID> base = generator.emitNode(m_expr); 3703 3754 RefPtr<RegisterID> local = this->tryGetBoundLocal(generator); 3704 3755 RefPtr<RegisterID> enumeratorIndex; … … 3778 3829 generator.emitProfileControlFlow(profilerStartOffset); 3779 3830 3780 generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get() );3831 generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get(), base.get()); 3781 3832 generator.emitNode(dst, m_statement); 3782 3833 generator.popStructureForInScope(local.get());
Note:
See TracChangeset
for help on using the changeset viewer.