WebKit Bugzilla
Attachment 350195 Details for
Bug 189785
: Convert op_to_this to store mutable data in a side table
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-189785-20180920065423.patch (text/plain), 93.00 KB, created by
Tadeu Zagallo
on 2018-09-20 06:54:38 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Tadeu Zagallo
Created:
2018-09-20 06:54:38 PDT
Size:
93.00 KB
patch
obsolete
>Subversion Revision: 236149 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 6ce7c338fef3372e56aa274e7498cc0fb810c6fc..928c4f85028d3b25ba4a3c84af85dfe87d6bfbd7 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,80 @@ >+2018-09-20 Tadeu Zagallo <tzagallo@apple.com> >+ >+ Convert op_to_this to store mutable data in a side table >+ https://bugs.webkit.org/show_bug.cgi?id=189785 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Convert op_to_this as a POC for https://bugs.webkit.org/show_bug.cgi?id=187373 >+ This patch does not change the encoding size of the bytecode, but >+ prevents all the writes to the operands of op_to_this in the stream, >+ as will happen with all opcodes in the upcoming patch. >+ >+ >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * bytecode/BytecodeDumper.cpp: >+ (JSC::BytecodeDumper<Block>::dumpValueProfiling): >+ (JSC::BytecodeDumper<CodeBlock>::dumpValueProfiling): >+ (JSC::BytecodeDumper<Block>::dumpOpToThis): >+ (JSC::BytecodeDumper<CodeBlock>::dumpOpToThis): >+ (JSC::BytecodeDumper<CodeBlock>::dumpArrayProfiling): >+ (JSC::printLocationAndOp): >+ (JSC::BytecodeDumper<Block>::printUnaryOp): >+ (JSC::BytecodeDumper<Block>::printBinaryOp): >+ (JSC::BytecodeDumper<Block>::printConditionalJump): >+ (JSC::BytecodeDumper<Block>::printCompareJump): >+ (JSC::BytecodeDumper<Block>::printGetByIdOp): >+ (JSC::BytecodeDumper<Block>::printCallOp): >+ (JSC::BytecodeDumper<Block>::printPutByIdOp): >+ (JSC::BytecodeDumper<Block>::printLocationOpAndRegisterOperand): >+ (JSC::BytecodeDumper<Block>::dumpBytecode): >+ (JSC::getToThisStatus): Deleted. >+ (JSC::getStructure): Deleted. >+ * bytecode/BytecodeDumper.h: >+ * bytecode/BytecodeList.json: >+ * bytecode/BytecodeUseDef.h: >+ (JSC::computeUsesForBytecodeOffset): >+ (JSC::computeDefsForBytecodeOffset): >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::CodeBlock): >+ (JSC::CodeBlock::finishCreation): >+ (JSC::CodeBlock::~CodeBlock): >+ (JSC::CodeBlock::finalizeLLIntInlineCaches): >+ (JSC::CodeBlock::tryGetValueProfileForBytecodeOffset): >+ (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset): >+ (JSC::CodeBlock::valueProfileForBytecodeOffset): >+ * bytecode/CodeBlock.h: >+ (JSC::CodeBlock::metadata): >+ (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset): Deleted. >+ * bytecode/Instruction.h: >+ (JSC::Instruction::as const): >+ * bytecode/OpToThis.h: Added. >+ (JSC::OpToThis::opcodeID): >+ (JSC::OpToThis::OpToThis): >+ (JSC::OpToThis::decode): >+ (JSC::OpToThis::Metadata::Metadata): >+ (JSC::OpToThis::metadata const): >+ (JSC::metadataSize): >+ * bytecode/UnlinkedCodeBlock.cpp: >+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock): >+ (JSC::UnlinkedCodeBlock::addMetadata): >+ * bytecode/UnlinkedCodeBlock.h: >+ (JSC::UnlinkedInstruction::as const): >+ * bytecompiler/BytecodeGenerator.cpp: >+ (JSC::BytecodeGenerator::emitToThis): >+ * dfg/DFGByteCodeParser.cpp: >+ (JSC::DFG::ByteCodeParser::parseBlock): >+ * jit/JITOpcodes.cpp: >+ (JSC::JIT::emit_op_to_this): >+ * jit/JITOpcodes32_64.cpp: >+ (JSC::JIT::emit_op_to_this): >+ * llint/LLIntOffsetsExtractor.cpp: >+ * llint/LowLevelInterpreter.asm: >+ * llint/LowLevelInterpreter32_64.asm: >+ * llint/LowLevelInterpreter64.asm: >+ * runtime/CommonSlowPaths.cpp: >+ (JSC::SLOW_PATH_DECL): >+ > 2018-09-17 Devin Rousso <drousso@apple.com> > > Web Inspector: generate CSSKeywordCompletions from backend values >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index 9c5c50c621b8b6e3fa738b3f96bb26b1adbd8dfe..d56dded332e77d5a3c7fba5acbea97f768b6b734 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -1110,6 +1110,7 @@ > 70ECA6061AFDBEA200449739 /* JSTemplateObjectDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6011AFDBEA200449739 /* JSTemplateObjectDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 70ECA6091AFDBEA200449739 /* TemplateObjectDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 70ECA6041AFDBEA200449739 /* TemplateObjectDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 72AAF7CE1D0D31B3005E60BE /* JSCustomGetterSetterFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */; }; >+ 7593C898BE714A64BE93A6E7 /* WasmContextInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A27958D7FA1142B0AC9E364D /* WasmContextInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 790081391E95A8EC0052D7CD /* WasmModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 790081371E95A8EC0052D7CD /* WasmModule.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 7905BB691D12050E0019FE57 /* InlineAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 7905BB671D12050E0019FE57 /* InlineAccess.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 79160DBE1C8E3EC8008C085A /* ProxyRevoke.h in Headers */ = {isa = PBXBuildFile; fileRef = 79160DBC1C8E3EC8008C085A /* ProxyRevoke.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -1523,7 +1524,6 @@ > AD2FCC211DB59CB200B3E736 /* WebAssemblyTablePrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCC151DB59C5900B3E736 /* WebAssemblyTablePrototype.lut.h */; }; > AD2FCC2D1DB838FD00B3E736 /* WebAssemblyPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCC271DB838C400B3E736 /* WebAssemblyPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; }; > AD412B341E7B2E9E008AF157 /* WasmContext.h in Headers */ = {isa = PBXBuildFile; fileRef = AD412B321E7B2E8A008AF157 /* WasmContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 7593C898BE714A64BE93A6E7 /* WasmContextInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A27958D7FA1142B0AC9E364D /* WasmContextInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; > AD4252511E5D0E14009D2A97 /* FullCodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4252501E5D0DEB009D2A97 /* FullCodeOrigin.h */; }; > AD4937C41DDBE6140077C807 /* AbstractModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937C21DDBE60A0077C807 /* AbstractModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; }; > AD4937C81DDD0AAE0077C807 /* WebAssemblyModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937C61DDCDCF00077C807 /* WebAssemblyModuleRecord.h */; }; >@@ -3183,6 +3183,7 @@ > 14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSContextRef.h; sourceTree = "<group>"; }; > 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSValueRef.cpp; sourceTree = "<group>"; }; > 14BD5A2D0A3E91F600BAF59C /* testapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testapi.c; path = API/tests/testapi.c; sourceTree = "<group>"; }; >+ 14BD68A22151D1E00050DAFF /* OpToThis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpToThis.h; sourceTree = "<group>"; }; > 14BE7D3217135CF400D1807A /* WeakInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakInlines.h; sourceTree = "<group>"; }; > 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMap.h; sourceTree = "<group>"; }; > 14CA958A16AB50DE00938A06 /* StaticPropertyAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticPropertyAnalyzer.h; sourceTree = "<group>"; }; >@@ -3993,6 +3994,7 @@ > A1D792FB1B43864B004516F5 /* IntlNumberFormatPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlNumberFormatPrototype.h; sourceTree = "<group>"; }; > A1E0451B1C25B4B100BB663C /* StringPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = StringPrototype.js; sourceTree = "<group>"; }; > A1FE1EB01C2C537E00A289FF /* DatePrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = DatePrototype.js; sourceTree = "<group>"; }; >+ A27958D7FA1142B0AC9E364D /* WasmContextInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmContextInlines.h; sourceTree = "<group>"; }; > A503FA13188E0FAF00110F14 /* JavaScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JavaScriptCallFrame.cpp; sourceTree = "<group>"; }; > A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCallFrame.h; sourceTree = "<group>"; }; > A503FA15188E0FB000110F14 /* JSJavaScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSJavaScriptCallFrame.cpp; sourceTree = "<group>"; }; >@@ -4346,7 +4348,6 @@ > AD2FCC271DB838C400B3E736 /* WebAssemblyPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyPrototype.h; path = js/WebAssemblyPrototype.h; sourceTree = "<group>"; }; > AD2FCC321DC4045300B3E736 /* WasmFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmFormat.cpp; sourceTree = "<group>"; }; > AD412B321E7B2E8A008AF157 /* WasmContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmContext.h; sourceTree = "<group>"; }; >- A27958D7FA1142B0AC9E364D /* WasmContextInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmContextInlines.h; sourceTree = "<group>"; }; > AD412B351E7B57C0008AF157 /* AllowMacroScratchRegisterUsageIf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllowMacroScratchRegisterUsageIf.h; sourceTree = "<group>"; }; > AD4252501E5D0DEB009D2A97 /* FullCodeOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullCodeOrigin.h; sourceTree = "<group>"; }; > AD4252521E5D0F22009D2A97 /* FullCodeOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FullCodeOrigin.cpp; sourceTree = "<group>"; }; >@@ -7728,6 +7729,7 @@ > FE64872D2141D04800AB0D3E /* OpcodeInlines.h */, > 0F2BDC2B151FDE8B00CD8910 /* Operands.h */, > A70447E917A0BD4600F5898E /* OperandsInlines.h */, >+ 14BD68A22151D1E00050DAFF /* OpToThis.h */, > E34E657420668E8E00FB81AC /* ParseHash.cpp */, > E34E657320668E8D00FB81AC /* ParseHash.h */, > 0FF9CE711B9CD6D0004EDCA6 /* PolymorphicAccess.cpp */, >@@ -7812,7 +7814,7 @@ > 9959E9251BD17F1E001AA413 /* Scripts */ = { > isa = PBXGroup; > children = ( >- 99DA00971BD598E000F4575C /* builtins */, >+ 99DA00971BD598E000F4575C /* wkbuiltins */, > 9959E9271BD17FA0001AA413 /* cssmin.py */, > 9959E92F1BD181F6001AA413 /* generate-combined-inspector-json.py */, > 99DA00AC1BD5993E00F4575C /* generate-js-builtins.py */, >@@ -7830,7 +7832,6 @@ > isa = PBXGroup; > children = ( > 99DA00991BD5992700F4575C /* __init__.py */, >- 99DA009D1BD5992700F4575C /* wkbuiltins.py */, > 99DA009E1BD5992700F4575C /* builtins_generate_combined_header.py */, > 99DA009F1BD5992700F4575C /* builtins_generate_combined_implementation.py */, > 412952731D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_header.py */, >@@ -7842,6 +7843,7 @@ > 99DA009A1BD5992700F4575C /* builtins_generator.py */, > 99DA009B1BD5992700F4575C /* builtins_model.py */, > 99DA009C1BD5992700F4575C /* builtins_templates.py */, >+ 99DA009D1BD5992700F4575C /* wkbuiltins.py */, > ); > path = wkbuiltins; > sourceTree = "<group>"; >@@ -8439,7 +8441,6 @@ > DE26E9031CB5DD0500D2BE82 /* BuiltinExecutableCreator.h in Headers */, > A7D801A51880D66E0026C39B /* BuiltinExecutables.h in Headers */, > A75EE9B218AAB7E200AAD043 /* BuiltinNames.h in Headers */, >- 99DA00A61BD5993100F4575C /* wkbuiltins.py in Headers */, > 99DA00A71BD5993100F4575C /* builtins_generate_combined_header.py in Headers */, > 99DA00A81BD5993100F4575C /* builtins_generate_combined_implementation.py in Headers */, > 412952771D2CF6BC00E78B89 /* builtins_generate_internals_wrapper_header.py in Headers */, >@@ -9689,6 +9690,7 @@ > ADBC54D51DF8EA2B005BF738 /* WebAssemblyToJSCallee.h in Headers */, > 52F6C35E1E71EB080081F4CC /* WebAssemblyWrapperFunction.h in Headers */, > BC18C47A0E16F5CD00B34460 /* WebKitAvailability.h in Headers */, >+ 99DA00A61BD5993100F4575C /* wkbuiltins.py in Headers */, > A7DCB97312E5193F00911940 /* WriteBarrier.h in Headers */, > C2B6D75318A33793004A9301 /* WriteBarrierInlines.h in Headers */, > 0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */, >diff --git a/Source/JavaScriptCore/bytecode/BytecodeDumper.cpp b/Source/JavaScriptCore/bytecode/BytecodeDumper.cpp >index 70bf712a2c6d83c71bf96c5e0a86397ebaa4452f..f4a07bd1c67f30854c9ba8bc0e0e08de95d6f1b8 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeDumper.cpp >+++ b/Source/JavaScriptCore/bytecode/BytecodeDumper.cpp >@@ -33,6 +33,7 @@ > #include "Error.h" > #include "HeapInlines.h" > #include "InterpreterInlines.h" >+#include "OpToThis.h" > #include "PolymorphicAccess.h" > #include "PutByIdFlags.h" > #include "StructureInlines.h" >@@ -71,16 +72,6 @@ static PutByIdFlags getPutByIdFlags(const UnlinkedInstruction& instruction) > return static_cast<PutByIdFlags>(instruction.u.operand); > } > >-static ToThisStatus getToThisStatus(const Instruction& instruction) >-{ >- return instruction.u.toThisStatus; >-} >- >-static ToThisStatus getToThisStatus(const UnlinkedInstruction& instruction) >-{ >- return static_cast<ToThisStatus>(instruction.u.operand); >-} >- > static void* getPointer(const Instruction& instruction) > { > return instruction.u.pointer; >@@ -101,16 +92,6 @@ static StructureChain* getStructureChain(const UnlinkedInstruction&) > return nullptr; > } > >-static Structure* getStructure(const Instruction& instruction) >-{ >- return instruction.u.structure.get(); >-} >- >-static Structure* getStructure(const UnlinkedInstruction&) >-{ >- return nullptr; >-} >- > static LLIntCallLinkInfo* getCallLinkInfo(const Instruction& instruction) > { > return instruction.u.callLinkInfo; >@@ -155,24 +136,56 @@ static void beginDumpProfiling(PrintStream& out, bool& hasPrintedProfiling) > } > > template<class Block> >-void BytecodeDumper<Block>::dumpValueProfiling(PrintStream&, const typename Block::Instruction*& it, bool&) >+void BytecodeDumper<Block>::dumpValueProfiling(PrintStream&, ValueProfile*, bool&) > { >- ++it; > } > > template<> >-void BytecodeDumper<CodeBlock>::dumpValueProfiling(PrintStream& out, const typename CodeBlock::Instruction*& it, bool& hasPrintedProfiling) >+void BytecodeDumper<CodeBlock>::dumpValueProfiling(PrintStream& out, ValueProfile* profile, bool& hasPrintedProfiling) > { > ConcurrentJSLocker locker(block()->m_lock); > >- ++it; >- CString description = it->u.profile->briefDescription(locker); >+ CString description = profile->briefDescription(locker); > if (!description.length()) > return; > beginDumpProfiling(out, hasPrintedProfiling); > out.print(description); > } > >+template<class Block> >+void BytecodeDumper<Block>::dumpValueProfiling(PrintStream&, const typename Block::Instruction*& it, bool&) >+{ >+ ++it; >+} >+ >+template<> >+void BytecodeDumper<CodeBlock>::dumpValueProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling) >+{ >+ ++it; >+ dumpValueProfiling(out, it->u.profile, hasPrintedProfiling); >+} >+ >+template<class Block> >+void BytecodeDumper<Block>::dumpOpToThis(PrintStream& out, int location, OpToThis bytecode, bool&) >+{ >+ int r0 = bytecode.srcDst.offset(); >+ printLocationOpAndRegisterOperand(out, location, "to_this", r0); >+} >+ >+ >+template<> >+void BytecodeDumper<CodeBlock>::dumpOpToThis(PrintStream& out, int location, OpToThis bytecode, bool& hasPrintedProfiling) >+{ >+ auto& metadata = bytecode.metadata(block()); >+ int r0 = bytecode.srcDst.offset(); >+ printLocationOpAndRegisterOperand(out, location, "to_this", r0); >+ Structure* structure = metadata.cachedStructure.get(); >+ if (structure) >+ out.print(", cache(struct = ", RawPointer(structure), ")"); >+ out.print(", ", metadata.toThisStatus); >+ dumpValueProfiling(out, &metadata.profile, hasPrintedProfiling); >+} >+ > template<class Block> > void BytecodeDumper<Block>::dumpArrayProfiling(PrintStream&, const typename Block::Instruction*& it, bool&) > { >@@ -250,8 +263,7 @@ const Identifier& BytecodeDumper<Block>::identifier(int index) const > return block()->identifier(index); > } > >-template<class Instruction> >-static void printLocationAndOp(PrintStream& out, int location, const Instruction*&, const char* op) >+static void printLocationAndOp(PrintStream& out, int location, const char* op) > { > out.printf("[%4d] %-17s ", location, op); > } >@@ -311,7 +323,7 @@ void BytecodeDumper<Block>::printUnaryOp(PrintStream& out, int location, const t > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > >- printLocationAndOp(out, location, it, op); >+ printLocationAndOp(out, location, op); > out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); > } > >@@ -321,7 +333,7 @@ void BytecodeDumper<Block>::printBinaryOp(PrintStream& out, int location, const > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, op); >+ printLocationAndOp(out, location, op); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); > } > >@@ -330,7 +342,7 @@ void BytecodeDumper<Block>::printConditionalJump(PrintStream& out, const typenam > { > int r0 = (++it)->u.operand; > int offset = (++it)->u.operand; >- printLocationAndOp(out, location, it, op); >+ printLocationAndOp(out, location, op); > out.printf("%s, %d(->%d)", registerName(r0).data(), offset, location + offset); > } > >@@ -340,7 +352,7 @@ void BytecodeDumper<Block>::printCompareJump(PrintStream& out, const typename Bl > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int offset = (++it)->u.operand; >- printLocationAndOp(out, location, it, op); >+ printLocationAndOp(out, location, op); > out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset); > } > >@@ -370,7 +382,7 @@ void BytecodeDumper<Block>::printGetByIdOp(PrintStream& out, int location, const > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int id0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, op); >+ printLocationAndOp(out, location, op); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data()); > it += 4; // Increment up to the value profiler. > } >@@ -603,7 +615,7 @@ void BytecodeDumper<Block>::printCallOp(PrintStream& out, int location, const ty > int func = (++it)->u.operand; > int argCount = (++it)->u.operand; > int registerOffset = (++it)->u.operand; >- printLocationAndOp(out, location, it, op); >+ printLocationAndOp(out, location, op); > out.print(registerName(dst), ", ", registerName(func), ", ", argCount, ", ", registerOffset); > out.print(" (this at ", virtualRegisterForArgument(0, -registerOffset), ")"); > if (cacheDumpMode == DumpCaches) { >@@ -643,15 +655,15 @@ void BytecodeDumper<Block>::printPutByIdOp(PrintStream& out, int location, const > int r0 = (++it)->u.operand; > int id0 = (++it)->u.operand; > int r1 = (++it)->u.operand; >- printLocationAndOp(out, location, it, op); >+ printLocationAndOp(out, location, op); > out.printf("%s, %s, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data()); > it += 5; > } > > template<class Block> >-void BytecodeDumper<Block>::printLocationOpAndRegisterOperand(PrintStream& out, int location, const typename Block::Instruction*& it, const char* op, int operand) >+void BytecodeDumper<Block>::printLocationOpAndRegisterOperand(PrintStream& out, int location, const char* op, int operand) > { >- printLocationAndOp(out, location, it, op); >+ printLocationAndOp(out, location, op); > out.printf("%s", registerName(operand).data()); > } > >@@ -663,42 +675,42 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > OpcodeID opcode = Interpreter::getOpcodeID(*it); > switch (opcode) { > case op_enter: { >- printLocationAndOp(out, location, it, "enter"); >+ printLocationAndOp(out, location, "enter"); > break; > } > case op_get_scope: { > int r0 = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "get_scope", r0); >+ printLocationOpAndRegisterOperand(out, location, "get_scope", r0); > break; > } > case op_create_direct_arguments: { > int r0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "create_direct_arguments"); >+ printLocationAndOp(out, location, "create_direct_arguments"); > out.printf("%s", registerName(r0).data()); > break; > } > case op_create_scoped_arguments: { > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "create_scoped_arguments"); >+ printLocationAndOp(out, location, "create_scoped_arguments"); > out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); > break; > } > case op_create_cloned_arguments: { > int r0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "create_cloned_arguments"); >+ printLocationAndOp(out, location, "create_cloned_arguments"); > out.printf("%s", registerName(r0).data()); > break; > } > case op_argument_count: { > int r0 = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "argument_count", r0); >+ printLocationOpAndRegisterOperand(out, location, "argument_count", r0); > break; > } > case op_get_argument: { > int r0 = (++it)->u.operand; > int index = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "argument", r0); >+ printLocationOpAndRegisterOperand(out, location, "argument", r0); > out.printf(", %d", index); > dumpValueProfiling(out, it, hasPrintedProfiling); > break; >@@ -707,14 +719,14 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > unsigned argumentOffset = (++it)->u.unsignedValue; >- printLocationAndOp(out, location, it, "create_rest"); >+ printLocationAndOp(out, location, "create_rest"); > out.printf("%s, %s, ", registerName(r0).data(), registerName(r1).data()); > out.printf("ArgumentsOffset: %u", argumentOffset); > break; > } > case op_get_rest_length: { > int r0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "get_rest_length"); >+ printLocationAndOp(out, location, "get_rest_length"); > out.printf("%s, ", registerName(r0).data()); > unsigned argumentOffset = (++it)->u.unsignedValue; > out.printf("ArgumentsOffset: %u", argumentOffset); >@@ -725,29 +737,24 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r1 = (++it)->u.operand; > unsigned inferredInlineCapacity = (++it)->u.operand; > unsigned cachedFunction = (++it)->u.operand; >- printLocationAndOp(out, location, it, "create_this"); >+ printLocationAndOp(out, location, "create_this"); > out.printf("%s, %s, %u, %u", registerName(r0).data(), registerName(r1).data(), inferredInlineCapacity, cachedFunction); > break; > } > case op_to_this: { >- int r0 = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "to_this", r0); >- Structure* structure = getStructure(*(++it)); >- if (structure) >- out.print(", cache(struct = ", RawPointer(structure), ")"); >- out.print(", ", getToThisStatus(*(++it))); >- dumpValueProfiling(out, it, hasPrintedProfiling); >+ dumpOpToThis(out, location, it->template as<OpToThis>(), hasPrintedProfiling); >+ it += opcodeLength(op_to_this) - 1; > break; > } > case op_check_tdz: { > int r0 = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "op_check_tdz", r0); >+ printLocationOpAndRegisterOperand(out, location, "op_check_tdz", r0); > break; > } > case op_new_object: { > int r0 = (++it)->u.operand; > unsigned inferredInlineCapacity = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_object"); >+ printLocationAndOp(out, location, "new_object"); > out.printf("%s, %u", registerName(r0).data(), inferredInlineCapacity); > ++it; // Skip object allocation profile. > break; >@@ -756,7 +763,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int dst = (++it)->u.operand; > int argv = (++it)->u.operand; > int argc = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_array"); >+ printLocationAndOp(out, location, "new_array"); > out.printf("%s, %s, %d", registerName(dst).data(), registerName(argv).data(), argc); > ++it; // Skip array allocation profile. > break; >@@ -765,7 +772,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int dst = (++it)->u.operand; > int argv = (++it)->u.operand; > int argc = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_array_with_spread"); >+ printLocationAndOp(out, location, "new_array_with_spread"); > out.printf("%s, %s, %d, ", registerName(dst).data(), registerName(argv).data(), argc); > unsigned bitVectorIndex = (++it)->u.unsignedValue; > const BitVector& bitVector = block()->bitVector(bitVectorIndex); >@@ -781,14 +788,14 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > case op_spread: { > int dst = (++it)->u.operand; > int arg = (++it)->u.operand; >- printLocationAndOp(out, location, it, "spread"); >+ printLocationAndOp(out, location, "spread"); > out.printf("%s, %s", registerName(dst).data(), registerName(arg).data()); > break; > } > case op_new_array_with_size: { > int dst = (++it)->u.operand; > int length = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_array_with_size"); >+ printLocationAndOp(out, location, "new_array_with_size"); > out.printf("%s, %s", registerName(dst).data(), registerName(length).data()); > ++it; // Skip array allocation profile. > break; >@@ -796,7 +803,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > case op_new_array_buffer: { > int dst = (++it)->u.operand; > int array = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_array_buffer"); >+ printLocationAndOp(out, location, "new_array_buffer"); > out.printf("%s, %s", registerName(dst).data(), registerName(array).data()); > ++it; // Skip array allocation profile. > break; >@@ -804,14 +811,14 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > case op_new_regexp: { > int r0 = (++it)->u.operand; > int re0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_regexp"); >+ printLocationAndOp(out, location, "new_regexp"); > out.printf("%s, %s", registerName(r0).data(), registerName(re0).data()); > break; > } > case op_mov: { > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "mov"); >+ printLocationAndOp(out, location, "mov"); > out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); > break; > } >@@ -821,13 +828,13 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > ++it; > ++it; > ++it; >- printLocationAndOp(out, location, it, "op_profile_type"); >+ printLocationAndOp(out, location, "op_profile_type"); > out.printf("%s", registerName(r0).data()); > break; > } > case op_profile_control_flow: { > BasicBlockLocation* basicBlockLocation = getBasicBlockLocation(*(++it)); >- printLocationAndOp(out, location, it, "profile_control_flow"); >+ printLocationAndOp(out, location, "profile_control_flow"); > if (basicBlockLocation) > out.printf("[%d, %d]", basicBlockLocation->startOffset(), basicBlockLocation->endOffset()); > break; >@@ -886,12 +893,12 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > } > case op_inc: { > int r0 = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "inc", r0); >+ printLocationOpAndRegisterOperand(out, location, "inc", r0); > break; > } > case op_dec: { > int r0 = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "dec", r0); >+ printLocationOpAndRegisterOperand(out, location, "dec", r0); > break; > } > case op_to_number: { >@@ -974,7 +981,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "overrides_has_instance"); >+ printLocationAndOp(out, location, "overrides_has_instance"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); > break; > } >@@ -982,7 +989,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "instanceof"); >+ printLocationAndOp(out, location, "instanceof"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); > break; > } >@@ -991,7 +998,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; > int r3 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "instanceof_custom"); >+ printLocationAndOp(out, location, "instanceof_custom"); > out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data()); > break; > } >@@ -1023,7 +1030,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int type = (++it)->u.operand; >- printLocationAndOp(out, location, it, "is_cell_with_type"); >+ printLocationAndOp(out, location, "is_cell_with_type"); > out.printf("%s, %s, %d", registerName(r0).data(), registerName(r1).data(), type); > break; > } >@@ -1043,7 +1050,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int id0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "in_by_id"); >+ printLocationAndOp(out, location, "in_by_id"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data()); > printInByIdCacheStatus(out, location, statusMap); > break; >@@ -1057,7 +1064,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int id0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "try_get_by_id"); >+ printLocationAndOp(out, location, "try_get_by_id"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data()); > dumpValueProfiling(out, it, hasPrintedProfiling); > break; >@@ -1066,7 +1073,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int id0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "get_by_id_direct"); >+ printLocationAndOp(out, location, "get_by_id_direct"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data()); > it += 2; // Increment up to the value profiler. > printGetByIdCacheStatus(out, location, statusMap); >@@ -1083,7 +1090,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > break; > } > case op_get_by_id_with_this: { >- printLocationAndOp(out, location, it, "get_by_id_with_this"); >+ printLocationAndOp(out, location, "get_by_id_with_this"); > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; >@@ -1097,7 +1104,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; > int r3 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "get_by_val_with_this"); >+ printLocationAndOp(out, location, "get_by_val_with_this"); > out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data()); > dumpValueProfiling(out, it, hasPrintedProfiling); > break; >@@ -1112,7 +1119,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r1 = (++it)->u.operand; > int id0 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_by_id_with_this"); >+ printLocationAndOp(out, location, "put_by_id_with_this"); > out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data(), registerName(r2).data()); > break; > } >@@ -1121,7 +1128,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; > int r3 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_by_val_with_this"); >+ printLocationAndOp(out, location, "put_by_val_with_this"); > out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data()); > break; > } >@@ -1130,7 +1137,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int id0 = (++it)->u.operand; > int n0 = (++it)->u.operand; > int r1 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_getter_by_id"); >+ printLocationAndOp(out, location, "put_getter_by_id"); > out.printf("%s, %s, %d, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), n0, registerName(r1).data()); > break; > } >@@ -1139,7 +1146,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int id0 = (++it)->u.operand; > int n0 = (++it)->u.operand; > int r1 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_setter_by_id"); >+ printLocationAndOp(out, location, "put_setter_by_id"); > out.printf("%s, %s, %d, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), n0, registerName(r1).data()); > break; > } >@@ -1149,7 +1156,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int n0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_getter_setter_by_id"); >+ printLocationAndOp(out, location, "put_getter_setter_by_id"); > out.printf("%s, %s, %d, %s, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), n0, registerName(r1).data(), registerName(r2).data()); > break; > } >@@ -1158,7 +1165,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r1 = (++it)->u.operand; > int n0 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_getter_by_val"); >+ printLocationAndOp(out, location, "put_getter_by_val"); > out.printf("%s, %s, %d, %s", registerName(r0).data(), registerName(r1).data(), n0, registerName(r2).data()); > break; > } >@@ -1167,7 +1174,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r1 = (++it)->u.operand; > int n0 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_setter_by_val"); >+ printLocationAndOp(out, location, "put_setter_by_val"); > out.printf("%s, %s, %d, %s", registerName(r0).data(), registerName(r1).data(), n0, registerName(r2).data()); > break; > } >@@ -1176,7 +1183,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; > int r3 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "define_data_property"); >+ printLocationAndOp(out, location, "define_data_property"); > out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data()); > break; > } >@@ -1186,7 +1193,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r2 = (++it)->u.operand; > int r3 = (++it)->u.operand; > int r4 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "define_accessor_property"); >+ printLocationAndOp(out, location, "define_accessor_property"); > out.printf("%s, %s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data(), registerName(r4).data()); > break; > } >@@ -1194,7 +1201,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int id0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "del_by_id"); >+ printLocationAndOp(out, location, "del_by_id"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data()); > break; > } >@@ -1202,7 +1209,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "get_by_val"); >+ printLocationAndOp(out, location, "get_by_val"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); > dumpArrayProfiling(out, it, hasPrintedProfiling); > dumpValueProfiling(out, it, hasPrintedProfiling); >@@ -1212,7 +1219,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_by_val"); >+ printLocationAndOp(out, location, "put_by_val"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); > dumpArrayProfiling(out, it, hasPrintedProfiling); > break; >@@ -1221,7 +1228,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_by_val_direct"); >+ printLocationAndOp(out, location, "put_by_val_direct"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); > dumpArrayProfiling(out, it, hasPrintedProfiling); > break; >@@ -1230,13 +1237,13 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int r2 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "del_by_val"); >+ printLocationAndOp(out, location, "del_by_val"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data()); > break; > } > case op_jmp: { > int offset = (++it)->u.operand; >- printLocationAndOp(out, location, it, "jmp"); >+ printLocationAndOp(out, location, "jmp"); > out.printf("%d(->%d)", offset, location + offset); > break; > } >@@ -1260,7 +1267,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > Special::Pointer pointer = getSpecialPointer(*(++it)); > int offset = (++it)->u.operand; >- printLocationAndOp(out, location, it, "jneq_ptr"); >+ printLocationAndOp(out, location, "jneq_ptr"); > out.printf("%s, %d (%p), %d(->%d)", registerName(r0).data(), pointer, actualPointerFor(pointer), offset, location + offset); > ++it; > break; >@@ -1322,35 +1329,35 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > break; > } > case op_loop_hint: { >- printLocationAndOp(out, location, it, "loop_hint"); >+ printLocationAndOp(out, location, "loop_hint"); > break; > } > case op_check_traps: { >- printLocationAndOp(out, location, it, "check_traps"); >+ printLocationAndOp(out, location, "check_traps"); > break; > } > case op_nop: { >- printLocationAndOp(out, location, it, "nop"); >+ printLocationAndOp(out, location, "nop"); > break; > } > case op_super_sampler_begin: { >- printLocationAndOp(out, location, it, "super_sampler_begin"); >+ printLocationAndOp(out, location, "super_sampler_begin"); > break; > } > case op_super_sampler_end: { >- printLocationAndOp(out, location, it, "super_sampler_end"); >+ printLocationAndOp(out, location, "super_sampler_end"); > break; > } > case op_log_shadow_chicken_prologue: { > int r0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "log_shadow_chicken_prologue"); >+ printLocationAndOp(out, location, "log_shadow_chicken_prologue"); > out.printf("%s", registerName(r0).data()); > break; > } > case op_log_shadow_chicken_tail: { > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "log_shadow_chicken_tail"); >+ printLocationAndOp(out, location, "log_shadow_chicken_tail"); > out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); > break; > } >@@ -1358,7 +1365,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int tableIndex = (++it)->u.operand; > int defaultTarget = (++it)->u.operand; > int scrutineeRegister = (++it)->u.operand; >- printLocationAndOp(out, location, it, "switch_imm"); >+ printLocationAndOp(out, location, "switch_imm"); > out.printf("%d, %d(->%d), %s", tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).data()); > break; > } >@@ -1366,7 +1373,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int tableIndex = (++it)->u.operand; > int defaultTarget = (++it)->u.operand; > int scrutineeRegister = (++it)->u.operand; >- printLocationAndOp(out, location, it, "switch_char"); >+ printLocationAndOp(out, location, "switch_char"); > out.printf("%d, %d(->%d), %s", tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).data()); > break; > } >@@ -1374,7 +1381,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int tableIndex = (++it)->u.operand; > int defaultTarget = (++it)->u.operand; > int scrutineeRegister = (++it)->u.operand; >- printLocationAndOp(out, location, it, "switch_string"); >+ printLocationAndOp(out, location, "switch_string"); > out.printf("%d, %d(->%d), %s", tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).data()); > break; > } >@@ -1382,7 +1389,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int f0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_func"); >+ printLocationAndOp(out, location, "new_func"); > out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); > break; > } >@@ -1390,7 +1397,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int f0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_generator_func"); >+ printLocationAndOp(out, location, "new_generator_func"); > out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); > break; > } >@@ -1398,7 +1405,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int f0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_async_func"); >+ printLocationAndOp(out, location, "new_async_func"); > out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); > break; > } >@@ -1406,7 +1413,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int f0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_async_generator_func"); >+ printLocationAndOp(out, location, "new_async_generator_func"); > out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); > break; > } >@@ -1414,7 +1421,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int f0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_func_exp"); >+ printLocationAndOp(out, location, "new_func_exp"); > out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); > break; > } >@@ -1422,7 +1429,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int f0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_generator_func_exp"); >+ printLocationAndOp(out, location, "new_generator_func_exp"); > out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); > break; > } >@@ -1430,7 +1437,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int f0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "new_async_func_exp"); >+ printLocationAndOp(out, location, "new_async_func_exp"); > out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); > break; > } >@@ -1438,14 +1445,14 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int f0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "op_new_async_generator_func_exp"); >+ printLocationAndOp(out, location, "op_new_async_generator_func_exp"); > out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); > break; > } > case op_set_function_name: { > int funcReg = (++it)->u.operand; > int nameReg = (++it)->u.operand; >- printLocationAndOp(out, location, it, "set_function_name"); >+ printLocationAndOp(out, location, "set_function_name"); > out.printf("%s, %s", registerName(funcReg).data(), registerName(nameReg).data()); > break; > } >@@ -1485,7 +1492,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > else > RELEASE_ASSERT_NOT_REACHED(); > >- printLocationAndOp(out, location, it, opName); >+ printLocationAndOp(out, location, opName); > out.printf("%s, %s, %s, %s, %d, %d", registerName(result).data(), registerName(callee).data(), registerName(thisValue).data(), registerName(arguments).data(), firstFreeRegister, varArgOffset); > dumpValueProfiling(out, it, hasPrintedProfiling); > break; >@@ -1493,7 +1500,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > > case op_ret: { > int r0 = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "ret", r0); >+ printLocationOpAndRegisterOperand(out, location, "ret", r0); > break; > } > case op_construct: { >@@ -1504,21 +1511,21 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int count = (++it)->u.operand; >- printLocationAndOp(out, location, it, "strcat"); >+ printLocationAndOp(out, location, "strcat"); > out.printf("%s, %s, %d", registerName(r0).data(), registerName(r1).data(), count); > break; > } > case op_to_primitive: { > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "to_primitive"); >+ printLocationAndOp(out, location, "to_primitive"); > out.printf("%s, %s", registerName(r0).data(), registerName(r1).data()); > break; > } > case op_get_enumerable_length: { > int dst = it[1].u.operand; > int base = it[2].u.operand; >- printLocationAndOp(out, location, it, "op_get_enumerable_length"); >+ printLocationAndOp(out, location, "op_get_enumerable_length"); > out.printf("%s, %s", registerName(dst).data(), registerName(base).data()); > it += OPCODE_LENGTH(op_get_enumerable_length) - 1; > break; >@@ -1527,7 +1534,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int dst = (++it)->u.operand; > int base = (++it)->u.operand; > int propertyName = (++it)->u.operand; >- printLocationAndOp(out, location, it, "op_has_indexed_property"); >+ printLocationAndOp(out, location, "op_has_indexed_property"); > out.printf("%s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data()); > dumpArrayProfiling(out, it, hasPrintedProfiling); > break; >@@ -1537,7 +1544,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int base = it[2].u.operand; > int propertyName = it[3].u.operand; > int enumerator = it[4].u.operand; >- printLocationAndOp(out, location, it, "op_has_structure_property"); >+ printLocationAndOp(out, location, "op_has_structure_property"); > out.printf("%s, %s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), registerName(enumerator).data()); > it += OPCODE_LENGTH(op_has_structure_property) - 1; > break; >@@ -1546,7 +1553,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int dst = it[1].u.operand; > int base = it[2].u.operand; > int propertyName = it[3].u.operand; >- printLocationAndOp(out, location, it, "op_has_generic_property"); >+ printLocationAndOp(out, location, "op_has_generic_property"); > out.printf("%s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data()); > it += OPCODE_LENGTH(op_has_generic_property) - 1; > break; >@@ -1557,7 +1564,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int propertyName = (++it)->u.operand; > int index = (++it)->u.operand; > int enumerator = (++it)->u.operand; >- printLocationAndOp(out, location, it, "op_get_direct_pname"); >+ printLocationAndOp(out, location, "op_get_direct_pname"); > out.printf("%s, %s, %s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), registerName(index).data(), registerName(enumerator).data()); > dumpValueProfiling(out, it, hasPrintedProfiling); > break; >@@ -1566,7 +1573,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > case op_get_property_enumerator: { > int dst = it[1].u.operand; > int base = it[2].u.operand; >- printLocationAndOp(out, location, it, "op_get_property_enumerator"); >+ printLocationAndOp(out, location, "op_get_property_enumerator"); > out.printf("%s, %s", registerName(dst).data(), registerName(base).data()); > it += OPCODE_LENGTH(op_get_property_enumerator) - 1; > break; >@@ -1575,7 +1582,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int dst = it[1].u.operand; > int enumerator = it[2].u.operand; > int index = it[3].u.operand; >- printLocationAndOp(out, location, it, "op_enumerator_structure_pname"); >+ printLocationAndOp(out, location, "op_enumerator_structure_pname"); > out.printf("%s, %s, %s", registerName(dst).data(), registerName(enumerator).data(), registerName(index).data()); > it += OPCODE_LENGTH(op_enumerator_structure_pname) - 1; > break; >@@ -1584,7 +1591,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int dst = it[1].u.operand; > int enumerator = it[2].u.operand; > int index = it[3].u.operand; >- printLocationAndOp(out, location, it, "op_enumerator_generic_pname"); >+ printLocationAndOp(out, location, "op_enumerator_generic_pname"); > out.printf("%s, %s, %s", registerName(dst).data(), registerName(enumerator).data(), registerName(index).data()); > it += OPCODE_LENGTH(op_enumerator_generic_pname) - 1; > break; >@@ -1592,7 +1599,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > case op_to_index_string: { > int dst = it[1].u.operand; > int index = it[2].u.operand; >- printLocationAndOp(out, location, it, "op_to_index_string"); >+ printLocationAndOp(out, location, "op_to_index_string"); > out.printf("%s, %s", registerName(dst).data(), registerName(index).data()); > it += OPCODE_LENGTH(op_to_index_string) - 1; > break; >@@ -1601,14 +1608,14 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int dst = (++it)->u.operand; > int newScope = (++it)->u.operand; > int currentScope = (++it)->u.operand; >- printLocationAndOp(out, location, it, "push_with_scope"); >+ printLocationAndOp(out, location, "push_with_scope"); > out.printf("%s, %s, %s", registerName(dst).data(), registerName(newScope).data(), registerName(currentScope).data()); > break; > } > case op_get_parent_scope: { > int dst = (++it)->u.operand; > int parentScope = (++it)->u.operand; >- printLocationAndOp(out, location, it, "get_parent_scope"); >+ printLocationAndOp(out, location, "get_parent_scope"); > out.printf("%s, %s", registerName(dst).data(), registerName(parentScope).data()); > break; > } >@@ -1617,7 +1624,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int scope = (++it)->u.operand; > int symbolTable = (++it)->u.operand; > int initialValue = (++it)->u.operand; >- printLocationAndOp(out, location, it, "create_lexical_environment"); >+ printLocationAndOp(out, location, "create_lexical_environment"); > out.printf("%s, %s, %s, %s", > registerName(dst).data(), registerName(scope).data(), registerName(symbolTable).data(), registerName(initialValue).data()); > break; >@@ -1626,19 +1633,19 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > void* pointer = getPointer(*(++it)); >- printLocationAndOp(out, location, it, "catch"); >+ printLocationAndOp(out, location, "catch"); > out.printf("%s, %s, %p", registerName(r0).data(), registerName(r1).data(), pointer); > break; > } > case op_throw: { > int r0 = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "throw", r0); >+ printLocationOpAndRegisterOperand(out, location, "throw", r0); > break; > } > case op_throw_static_error: { > int r0 = (++it)->u.operand; > ErrorType k1 = static_cast<ErrorType>((++it)->u.unsignedValue); >- printLocationAndOp(out, location, it, "throw_static_error"); >+ printLocationAndOp(out, location, "throw_static_error"); > out.printf("%s, ", registerName(r0).data()); > out.print(k1); > break; >@@ -1646,7 +1653,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > case op_debug: { > int debugHookType = (++it)->u.operand; > int hasBreakpointFlag = (++it)->u.operand; >- printLocationAndOp(out, location, it, "debug"); >+ printLocationAndOp(out, location, "debug"); > out.printf("%s, %d", debugHookName(debugHookType), hasBreakpointFlag); > break; > } >@@ -1654,24 +1661,24 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > ++it; // Profile top half > ++it; // Profile bottom half >- printLocationAndOp(out, location, it, "identity_with_profile"); >+ printLocationAndOp(out, location, "identity_with_profile"); > out.printf("%s", registerName(r0).data()); > break; > } > case op_unreachable: { >- printLocationAndOp(out, location, it, "unreachable"); >+ printLocationAndOp(out, location, "unreachable"); > break; > } > case op_end: { > int r0 = (++it)->u.operand; >- printLocationOpAndRegisterOperand(out, location, it, "end", r0); >+ printLocationOpAndRegisterOperand(out, location, "end", r0); > break; > } > case op_resolve_scope_for_hoisting_func_decl_in_eval: { > int r0 = (++it)->u.operand; > int scope = (++it)->u.operand; > int id0 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "resolve_scope_for_hoisting_func_decl_in_eval"); >+ printLocationAndOp(out, location, "resolve_scope_for_hoisting_func_decl_in_eval"); > out.printf("%s, %s, %s", registerName(r0).data(), registerName(scope).data(), idName(id0, identifier(id0)).data()); > break; > } >@@ -1682,7 +1689,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > ResolveType resolveType = static_cast<ResolveType>((++it)->u.operand); > int depth = (++it)->u.operand; > void* pointer = getPointer(*(++it)); >- printLocationAndOp(out, location, it, "resolve_scope"); >+ printLocationAndOp(out, location, "resolve_scope"); > out.printf("%s, %s, %s, <%s>, %d, %p", registerName(r0).data(), registerName(scope).data(), idName(id0, identifier(id0)).data(), resolveTypeName(resolveType), depth, pointer); > break; > } >@@ -1693,7 +1700,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > GetPutInfo getPutInfo = GetPutInfo((++it)->u.operand); > ++it; // Structure > int operand = (++it)->u.operand; // Operand >- printLocationAndOp(out, location, it, "get_from_scope"); >+ printLocationAndOp(out, location, "get_from_scope"); > out.print(registerName(r0), ", ", registerName(r1)); > if (static_cast<unsigned>(id0) == UINT_MAX) > out.print(", anonymous"); >@@ -1710,7 +1717,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > GetPutInfo getPutInfo = GetPutInfo((++it)->u.operand); > ++it; // Structure > int operand = (++it)->u.operand; // Operand >- printLocationAndOp(out, location, it, "put_to_scope"); >+ printLocationAndOp(out, location, "put_to_scope"); > out.print(registerName(r0)); > if (static_cast<unsigned>(id0) == UINT_MAX) > out.print(", anonymous"); >@@ -1723,7 +1730,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int r1 = (++it)->u.operand; > int offset = (++it)->u.operand; >- printLocationAndOp(out, location, it, "get_from_arguments"); >+ printLocationAndOp(out, location, "get_from_arguments"); > out.printf("%s, %s, %d", registerName(r0).data(), registerName(r1).data(), offset); > dumpValueProfiling(out, it, hasPrintedProfiling); > break; >@@ -1732,7 +1739,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > int offset = (++it)->u.operand; > int r1 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "put_to_arguments"); >+ printLocationAndOp(out, location, "put_to_arguments"); > out.printf("%s, %d, %s", registerName(r0).data(), offset, registerName(r1).data()); > break; > } >@@ -1740,7 +1747,7 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block: > int r0 = (++it)->u.operand; > unsigned yieldPoint = (++it)->u.unsignedValue; > int r1 = (++it)->u.operand; >- printLocationAndOp(out, location, it, "yield"); >+ printLocationAndOp(out, location, "yield"); > out.printf("%s, %u, %s", registerName(r0).data(), yieldPoint, registerName(r1).data()); > break; > } >diff --git a/Source/JavaScriptCore/bytecode/BytecodeDumper.h b/Source/JavaScriptCore/bytecode/BytecodeDumper.h >index d811a8d7267cb33ab0a574ca684e29d95c4513b7..8e5cf06d27d2c32553b6491159c6913e392abaa5 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeDumper.h >+++ b/Source/JavaScriptCore/bytecode/BytecodeDumper.h >@@ -28,6 +28,7 @@ > > #include "CallLinkInfo.h" > #include "ICStatusMap.h" >+#include "OpToThis.h" > #include "StructureStubInfo.h" > > namespace JSC { >@@ -76,10 +77,12 @@ private: > enum CacheDumpMode { DumpCaches, DontDumpCaches }; > void printCallOp(PrintStream& out, int location, const Instruction*& it, const char* op, CacheDumpMode, bool& hasPrintedProfiling, const ICStatusMap&); > void printPutByIdOp(PrintStream& out, int location, const Instruction*& it, const char* op); >- void printLocationOpAndRegisterOperand(PrintStream& out, int location, const Instruction*& it, const char* op, int operand); >+ void printLocationOpAndRegisterOperand(PrintStream& out, int location, const char* op, int operand); > void dumpBytecode(PrintStream& out, const Instruction* begin, const Instruction*& it, const ICStatusMap&); >+ void dumpOpToThis(PrintStream& out, int location, OpToThis, bool& hasPrintedProfiling); > > void dumpValueProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling); >+ void dumpValueProfiling(PrintStream&, ValueProfile*, bool& hasPrintedProfiling); > void dumpArrayProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling); > void dumpProfilesForBytecodeOffset(PrintStream&, unsigned location, bool& hasPrintedProfiling); > >diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.json b/Source/JavaScriptCore/bytecode/BytecodeList.json >index f5bdc49a7a671b8de9cb348b7ebba936748b2f42..4598a6e76c52659db026c7f51f173b3fd9c3eb7d 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeList.json >+++ b/Source/JavaScriptCore/bytecode/BytecodeList.json >@@ -15,7 +15,7 @@ > {"cachedCallee" : "WriteBarrier<JSCell>"}]}, > { "name" : "op_get_argument", "length" : 4 }, > { "name" : "op_argument_count", "length" : 2 }, >- { "name" : "op_to_this", "length" : 5 }, >+ { "name" : "op_to_this", "length" : 3 }, > { "name" : "op_check_tdz", "length" : 2 }, > { "name" : "op_new_object", "length" : 4 }, > { "name" : "op_new_array", "length" : 5 }, >diff --git a/Source/JavaScriptCore/bytecode/BytecodeUseDef.h b/Source/JavaScriptCore/bytecode/BytecodeUseDef.h >index 3e3771f5b773ca3c3837dddb3d2c1470b2324f32..9c2a5b316d43fdf506ad367994008ffdd809a03d 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeUseDef.h >+++ b/Source/JavaScriptCore/bytecode/BytecodeUseDef.h >@@ -26,6 +26,7 @@ > #pragma once > > #include "CodeBlock.h" >+#include "OpToThis.h" > > namespace JSC { > >@@ -58,7 +59,6 @@ void computeUsesForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instructi > case op_super_sampler_end: > return; > case op_get_scope: >- case op_to_this: > case op_check_tdz: > case op_identity_with_profile: > case op_profile_type: >@@ -77,6 +77,11 @@ void computeUsesForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instructi > functor(codeBlock, instruction, opcodeID, instruction[1].u.operand); > return; > } >+ case op_to_this: { >+ auto bytecode = instruction->template as<OpToThis>(); >+ functor(codeBlock, instruction, opcodeID, bytecode.srcDst.offset()); >+ return; >+ } > case op_jlesseq: > case op_jgreater: > case op_jgreatereq: >@@ -490,7 +495,6 @@ void computeDefsForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instructi > case op_not: > case op_mov: > case op_new_object: >- case op_to_this: > case op_check_tdz: > case op_get_scope: > case op_create_direct_arguments: >@@ -507,6 +511,11 @@ void computeDefsForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instructi > functor(codeBlock, instruction, opcodeID, instruction[1].u.operand); > return; > } >+ case op_to_this: { >+ auto bytecode = instruction->template as<OpToThis>(); >+ functor(codeBlock, instruction, opcodeID, bytecode.srcDst.offset()); >+ return; >+ } > case op_catch: { > ASSERT(opcodeLengths[opcodeID] > 2); > functor(codeBlock, instruction, opcodeID, instruction[1].u.operand); >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >index 27af0fde2c08c5a54fb819d1acc3b134e76315e3..dab51285394298b3ff409a2c7fe12057690f414a 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -70,6 +70,8 @@ > #include "LowLevelInterpreter.h" > #include "ModuleProgramCodeBlock.h" > #include "ObjectAllocationProfileInlines.h" >+#include "OpToThis.h" >+#include "Opcode.h" > #include "PCToCodeOriginMap.h" > #include "PolymorphicAccess.h" > #include "ProfilerDatabase.h" >@@ -326,6 +328,7 @@ CodeBlock::CodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, CodeBlock > , m_osrExitCounter(0) > , m_optimizationDelayCounter(0) > , m_reoptimizationRetryCounter(0) >+ , m_metadata(other.m_metadata) > , m_creationTime(MonotonicTime::now()) > { > ASSERT(heap()->isDeferred()); >@@ -522,6 +525,13 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink > > RefCountedArray<Instruction> instructions(instructionCount); > >+ for (unsigned i = 0; i < numOpcodeIDs; i++) { >+ auto opcodeID = static_cast<OpcodeID>(i); >+ auto count = unlinkedCodeBlock->addMetadata(opcodeID); >+ if (count) >+ m_metadata[opcodeID] = reinterpret_cast<Instruction::Metadata*>(malloc(metadataSize(opcodeID) * count)); >+ } >+ > unsigned valueProfileCount = 0; > auto linkValueProfile = [&](unsigned bytecodeOffset, unsigned opLength) { > if (!vm.canUseJIT()) { >@@ -582,7 +592,12 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink > } > > case op_to_this: { >- linkValueProfile(i, opLength); >+ auto bytecode = pc->as<OpToThis>(); >+ auto& metadata = bytecode.metadata(this); >+ new (&metadata) OpToThis::Metadata(bytecode); >+ metadata.profile.m_bytecodeOffset = i; >+ metadata.cachedStructure.clear(); >+ metadata.toThisStatus = ToThisOK; > break; > } > >@@ -904,6 +919,11 @@ CodeBlock::~CodeBlock() > stub->deref(); > } > #endif // ENABLE(JIT) >+ >+ for (unsigned i = 0; i < numOpcodeIDs; i++) { >+ auto opcodeID = static_cast<OpcodeID>(i); >+ free(m_metadata[opcodeID]); >+ } > } > > void CodeBlock::setConstantIdentifierSetRegisters(VM& vm, const Vector<ConstantIndentifierSetEntry>& constants) >@@ -1303,15 +1323,16 @@ void CodeBlock::finalizeLLIntInlineCaches() > case op_get_by_id_unset: > case op_get_array_length: > break; >- case op_to_this: >- if (!curInstruction[2].u.structure || Heap::isMarked(curInstruction[2].u.structure.get())) >+ case op_to_this: { >+ auto& metadata = curInstruction->as<OpToThis>().metadata(this); >+ if (!metadata.cachedStructure || Heap::isMarked(metadata.cachedStructure.get())) > break; > if (Options::verboseOSR()) >- dataLogF("Clearing LLInt to_this with structure %p.\n", curInstruction[2].u.structure.get()); >- curInstruction[2].u.structure.clear(); >- curInstruction[3].u.toThisStatus = merge( >- curInstruction[3].u.toThisStatus, ToThisClearedByGC); >+ dataLogF("Clearing LLInt to_this with structure %p.\n", metadata.cachedStructure.get()); >+ metadata.cachedStructure.clear(); >+ metadata.toThisStatus = merge(metadata.toThisStatus, ToThisClearedByGC); > break; >+ } > case op_create_this: { > auto& cacheWriteBarrier = curInstruction[4].u.jsCell; > if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects()) >@@ -2807,14 +2828,37 @@ String CodeBlock::nameForRegister(VirtualRegister virtualRegister) > > ValueProfile* CodeBlock::tryGetValueProfileForBytecodeOffset(int bytecodeOffset) > { >+ ASSERT(Interpreter::getOpcodeID(instructions()[bytecodeOffset]) != op_to_this); >+ > return tryBinarySearch<ValueProfile, int>( > m_valueProfiles, m_valueProfiles.size(), bytecodeOffset, > getValueProfileBytecodeOffset<ValueProfile>); > } > >+ >+SpeculatedType CodeBlock::valueProfilePredictionForBytecodeOffset(const ConcurrentJSLocker& locker, int bytecodeOffset) >+{ >+ OpcodeID opcodeID = Interpreter::getOpcodeID(instructions()[bytecodeOffset]); >+ >+ if (opcodeID == op_to_this) { >+ Instruction* pc = &instructions()[bytecodeOffset]; >+ return pc->as<OpToThis>().metadata(this).profile.computeUpdatedPrediction(locker); >+ } >+ >+ if (ValueProfile* valueProfile = tryGetValueProfileForBytecodeOffset(bytecodeOffset)) >+ return valueProfile->computeUpdatedPrediction(locker); >+ return SpecNone; >+} >+ > ValueProfile& CodeBlock::valueProfileForBytecodeOffset(int bytecodeOffset) > { > OpcodeID opcodeID = Interpreter::getOpcodeID(instructions()[bytecodeOffset]); >+ >+ if (opcodeID == op_to_this) { >+ Instruction* pc = &instructions()[bytecodeOffset]; >+ return pc->as<OpToThis>().metadata(this).profile; >+ } >+ > unsigned length = opcodeLength(opcodeID); > ASSERT(!!tryGetValueProfileForBytecodeOffset(bytecodeOffset)); > return *instructions()[bytecodeOffset + length - 1].u.profile; >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h >index a3a3d263900d3122c09e204f32b57b3e101a32b2..1f04a13fa397049bef4cff5c9b2b3a678b2b0902 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h >@@ -427,12 +427,7 @@ public: > ValueProfile& valueProfile(int index) { return m_valueProfiles[index]; } > ValueProfile& valueProfileForBytecodeOffset(int bytecodeOffset); > ValueProfile* tryGetValueProfileForBytecodeOffset(int bytecodeOffset); >- SpeculatedType valueProfilePredictionForBytecodeOffset(const ConcurrentJSLocker& locker, int bytecodeOffset) >- { >- if (ValueProfile* valueProfile = tryGetValueProfileForBytecodeOffset(bytecodeOffset)) >- return valueProfile->computeUpdatedPrediction(locker); >- return SpecNone; >- } >+ SpeculatedType valueProfilePredictionForBytecodeOffset(const ConcurrentJSLocker&, int bytecodeOffset); > > unsigned totalNumberOfValueProfiles() > { >@@ -876,6 +871,12 @@ public: > > bool hasTailCalls() const { return m_unlinkedCode->hasTailCalls(); } > >+ template<typename Metadata> >+ Metadata& metadata(OpcodeID opcodeID, unsigned metadataID) >+ { >+ return reinterpret_cast<Metadata*>(m_metadata[opcodeID])[metadataID]; >+ } >+ > protected: > void finalizeLLIntInlineCaches(); > void finalizeBaselineJITInlineCaches(); >@@ -1010,6 +1011,8 @@ private: > uint16_t m_optimizationDelayCounter; > uint16_t m_reoptimizationRetryCounter; > >+ std::array<Instruction::Metadata*, numOpcodeIDs> m_metadata; >+ > MonotonicTime m_creationTime; > > std::unique_ptr<RareData> m_rareData; >diff --git a/Source/JavaScriptCore/bytecode/Instruction.h b/Source/JavaScriptCore/bytecode/Instruction.h >index c133578b3263d3029845e48379a35960704a6efd..0d0b073af745f27884549d8694004e516fea27cb 100644 >--- a/Source/JavaScriptCore/bytecode/Instruction.h >+++ b/Source/JavaScriptCore/bytecode/Instruction.h >@@ -55,6 +55,8 @@ typedef OpcodeID Opcode; > #endif > > struct Instruction { >+ struct Metadata { }; >+ > constexpr Instruction() > : u({ nullptr }) > { >@@ -118,6 +120,12 @@ struct Instruction { > Instruction(UniquedStringImpl* uid) { u.uid = uid; } > Instruction(bool* predicatePointer) { u.predicatePointer = predicatePointer; } > >+ template<typename T> >+ T as() const >+ { >+ return T::decode(this); >+ } >+ > union { > void* pointer; > Opcode opcode; >diff --git a/Source/JavaScriptCore/bytecode/OpToThis.h b/Source/JavaScriptCore/bytecode/OpToThis.h >new file mode 100644 >index 0000000000000000000000000000000000000000..248644478f779bccf995db92d4f217cf9008e2ce >--- /dev/null >+++ b/Source/JavaScriptCore/bytecode/OpToThis.h >@@ -0,0 +1,91 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All Rights Reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "CodeBlock.h" >+#include "Instruction.h" >+#include "LLIntData.h" >+#include "Opcode.h" >+#include "UnlinkedCodeBlock.h" >+#include "ValueProfile.h" >+#include "VirtualRegister.h" >+ >+namespace JSC { >+ >+struct OpToThis : public Instruction { >+ static constexpr OpcodeID opcodeID() { return op_to_this; } >+ >+ OpToThis(const UnlinkedInstruction* pc) >+ : srcDst(pc[1].u.operand) >+ , metadataID(pc[2].u.unsignedValue) >+ { } >+ >+ OpToThis(const Instruction* pc) >+ : srcDst(pc[1].u.operand) >+ , metadataID(pc[2].u.unsignedValue) >+ { } >+ >+ static OpToThis decode(const Instruction* pc) >+ { >+ ASSERT(pc[0].u.opcode == LLInt::getOpcode(opcodeID())); >+ return { pc }; >+ } >+ >+ static OpToThis decode(const UnlinkedInstruction* pc) >+ { >+ ASSERT(pc[0].u.opcode == opcodeID()); >+ return { pc }; >+ } >+ >+ struct Metadata : public Instruction::Metadata { >+ Metadata(const OpToThis&) { } >+ >+ WriteBarrierBase<Structure> cachedStructure; >+ ToThisStatus toThisStatus; >+ ValueProfile profile; >+ }; >+ >+ Metadata& metadata(CodeBlock* codeBlock) const >+ { >+ return codeBlock->metadata<Metadata>(opcodeID(), metadataID); >+ } >+ >+ Metadata& metadata(ExecState* exec) const >+ { >+ return metadata(exec->codeBlock()); >+ } >+ >+ VirtualRegister srcDst; >+ unsigned metadataID; >+}; >+ >+inline size_t metadataSize(OpcodeID opcodeID) >+{ >+ ASSERT(opcodeID == op_to_this); >+ return sizeof(OpToThis::Metadata); >+} >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp >index 2e2d64f06f97fa1da5625ba6b584dcfd8d911d0b..19b3a0bc9bf334beb0b548ef83096752c8724690 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp >@@ -55,6 +55,7 @@ const ClassInfo UnlinkedCodeBlock::s_info = { "UnlinkedCodeBlock", nullptr, null > UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info, DebuggerMode debuggerMode) > : Base(*vm, structure) > , m_globalObjectRegister(VirtualRegister()) >+ , m_metadata(numOpcodeIDs, 0) > , m_usesEval(info.usesEval()) > , m_isStrictMode(info.isStrictMode()) > , m_isConstructor(info.isConstructor()) >@@ -425,4 +426,9 @@ BytecodeLivenessAnalysis& UnlinkedCodeBlock::livenessAnalysisSlow(CodeBlock* cod > return *m_liveness; > } > >+unsigned UnlinkedCodeBlock::addMetadata(OpcodeID opcodeID) >+{ >+ return m_metadata[opcodeID]++; >+} >+ > } // namespace JSC >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >index da77bc9379dc522445989498b7ea98776d92d162..99fb2a9c39e91c9c909abe69e969d6b642b70a01 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >@@ -33,6 +33,7 @@ > #include "Identifier.h" > #include "JSCast.h" > #include "LockDuringMarking.h" >+#include "Opcode.h" > #include "ParserModes.h" > #include "RegExp.h" > #include "SpecialPointer.h" >@@ -110,6 +111,12 @@ struct UnlinkedInstruction { > int32_t operand; > unsigned unsignedValue; > } u; >+ >+ template<typename T> >+ T as() const >+ { >+ return T::decode(this); >+ } > }; > > class UnlinkedCodeBlock : public JSCell { >@@ -388,6 +395,8 @@ public: > DFG::ExitProfile& exitProfile() { return m_exitProfile; } > #endif > >+ unsigned addMetadata(OpcodeID); >+ > protected: > UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&, DebuggerMode); > ~UnlinkedCodeBlock(); >@@ -423,6 +432,7 @@ private: > > String m_sourceURLDirective; > String m_sourceMappingURLDirective; >+ Vector<unsigned, numOpcodeIDs> m_metadata; > > #if ENABLE(DFG_JIT) > DFG::ExitProfile m_exitProfile; >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >index da6febeb4d1ca5416a05a53986355a7c857b602a..7e9b397d7431c9c1c08e1cdfe0478695eadd3df0 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >@@ -5238,11 +5238,9 @@ void IndexedForInContext::finalize(BytecodeGenerator& generator) > void BytecodeGenerator::emitToThis() > { > m_codeBlock->addPropertyAccessInstruction(instructions().size()); >- UnlinkedValueProfile profile = emitProfiledOpcode(op_to_this); >+ emitOpcode(op_to_this); > instructions().append(kill(&m_thisRegister)); >- instructions().append(0); >- instructions().append(0); >- instructions().append(profile); >+ instructions().append(m_codeBlock->addMetadata(op_to_this)); > } > > } // namespace JSC >diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >index f106149fbf059d2c2938fa2908bd16911ca08c7a..3cbfa6cd45b9e7a93d03d483a4f94db5e8b08d95 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -57,6 +57,7 @@ > #include "JSModuleNamespaceObject.h" > #include "NumberConstructor.h" > #include "ObjectConstructor.h" >+#include "OpToThis.h" > #include "OpcodeInlines.h" > #include "PreciseJumpTargets.h" > #include "PutByIdFlags.h" >@@ -4667,8 +4668,11 @@ void ByteCodeParser::parseBlock(unsigned limit) > case op_to_this: { > Node* op1 = getThis(); > if (op1->op() != ToThis) { >- Structure* cachedStructure = currentInstruction[2].u.structure.get(); >- if (currentInstruction[3].u.toThisStatus != ToThisOK >+ auto bytecode = currentInstruction->as<OpToThis>(); >+ auto& metadata = bytecode.metadata(m_codeBlock); >+ >+ Structure* cachedStructure = metadata.cachedStructure.get(); >+ if (metadata.toThisStatus != ToThisOK > || !cachedStructure > || cachedStructure->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis > || m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex) >diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp >index 6abfbb85215835d1d4bd8edcd89141d2b3876253..fd102e11926845d702166d0ec1cc27b480d5e4ae 100644 >--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp >+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp >@@ -40,6 +40,7 @@ > #include "JSPropertyNameEnumerator.h" > #include "LinkBuffer.h" > #include "MaxFrameExtentForSlowPathCall.h" >+#include "OpToThis.h" > #include "OpcodeInlines.h" > #include "SlowPathCall.h" > #include "SuperSampler.h" >@@ -812,8 +813,10 @@ void JIT::emit_op_get_scope(Instruction* currentInstruction) > > void JIT::emit_op_to_this(Instruction* currentInstruction) > { >- WriteBarrierBase<Structure>* cachedStructure = ¤tInstruction[2].u.structure; >- emitGetVirtualRegister(currentInstruction[1].u.operand, regT1); >+ auto bytecode = currentInstruction->as<OpToThis>(); >+ auto& metadata = bytecode.metadata(m_codeBlock); >+ WriteBarrierBase<Structure>* cachedStructure = &metadata.cachedStructure; >+ emitGetVirtualRegister(bytecode.srcDst.offset(), regT1); > > emitJumpSlowCaseIfNotJSCell(regT1); > >diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp >index f5a394bee78713e4fbd40664c01c799479e91e20..b7b35d76fbfbc7fa33b64d95bd368da67661a90b 100644 >--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp >+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp >@@ -972,8 +972,10 @@ void JIT::emit_op_create_this(Instruction* currentInstruction) > > void JIT::emit_op_to_this(Instruction* currentInstruction) > { >- WriteBarrierBase<Structure>* cachedStructure = ¤tInstruction[2].u.structure; >- int thisRegister = currentInstruction[1].u.operand; >+ auto bytecode = currentInstruction->as<OpToThis>(); >+ auto& metadata = bytecode.metadata(m_codeBlock); >+ WriteBarrierBase<Structure>* cachedStructure = &metadata.cachedStructure; >+ int thisRegister = bytecode.srcDst.offset(); > > emitLoad(thisRegister, regT3, regT2); > >diff --git a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp >index 4bfd6e982d4a0450032e3699891973f84e5d9c04..074e3cae87579df7c88cc3bd4813231af897f96e 100644 >--- a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp >+++ b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp >@@ -51,6 +51,7 @@ > #include "LLIntOfflineAsmConfig.h" > #include "MarkedSpace.h" > #include "NativeExecutable.h" >+#include "OpToThis.h" > #include "ProtoCallFrame.h" > #include "ShadowChicken.h" > #include "Structure.h" >diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm >index 2b4350cd52a873f14b5c8776eb4fb9c3d04fa3d8..6c67353a5fe11b48bcf7b2d1458e564307bc6029 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm >@@ -276,14 +276,17 @@ if JSVALUE64 > # This requires an add before the call, and a sub after. > const PC = t4 # When changing this, make sure LLIntPC is up to date in LLIntPCRanges.h > if ARM64 or ARM64E >+ const metadataTable = csr6 > const PB = csr7 > const tagTypeNumber = csr8 > const tagMask = csr9 > elsif X86_64 >+ const metadataTable = csr1 > const PB = csr2 > const tagTypeNumber = csr3 > const tagMask = csr4 > elsif X86_64_WIN >+ const metadataTable = csr3 > const PB = csr4 > const tagTypeNumber = csr5 > const tagMask = csr6 >@@ -291,6 +294,7 @@ if JSVALUE64 > const PB = csr0 > const tagTypeNumber = csr1 > const tagMask = csr2 >+ const metadataTable = csr3 > end > > macro loadisFromInstruction(offset, dest) >@@ -480,6 +484,10 @@ macro assert(assertion) > end > end > >+macro getOperand(offset, dst) >+ loadisFromInstruction(offset, dst) >+end >+ > # The probe macro can be used to insert some debugging code without perturbing scalar > # registers. Presently, the probe macro only preserves scalar registers. Hence, the > # C probe callback function should not trash floating point registers. >@@ -655,7 +663,7 @@ macro preserveCalleeSavesUsedByLLInt() > elsif ARMv7 > elsif ARM64 or ARM64E > emit "stp x27, x28, [x29, #-16]" >- emit "stp xzr, x26, [x29, #-32]" >+ emit "stp x25, x26, [x29, #-32]" > elsif MIPS > elsif X86 > elsif X86_WIN >@@ -663,10 +671,12 @@ macro preserveCalleeSavesUsedByLLInt() > storep csr4, -8[cfr] > storep csr3, -16[cfr] > storep csr2, -24[cfr] >+ storep csr1, -32[cfr] > elsif X86_64_WIN > storep csr6, -8[cfr] > storep csr5, -16[cfr] > storep csr4, -24[cfr] >+ storep csr3, -32[cfr] > end > end > >@@ -675,16 +685,18 @@ macro restoreCalleeSavesUsedByLLInt() > elsif ARM or ARMv7_TRADITIONAL > elsif ARMv7 > elsif ARM64 or ARM64E >- emit "ldp xzr, x26, [x29, #-32]" >+ emit "ldp x25, x26, [x29, #-32]" > emit "ldp x27, x28, [x29, #-16]" > elsif MIPS > elsif X86 > elsif X86_WIN > elsif X86_64 >+ loadp -32[cfr], csr1 > loadp -24[cfr], csr2 > loadp -16[cfr], csr3 > loadp -8[cfr], csr4 > elsif X86_64_WIN >+ loadp -32[cfr], csr3 > loadp -24[cfr], csr4 > loadp -16[cfr], csr5 > loadp -8[cfr], csr6 >@@ -1108,6 +1120,8 @@ macro prologue(codeBlockGetter, codeBlockSetter, osrSlowPath, traceSlowPath) > end > > if JSVALUE64 >+ loadp CodeBlock[cfr], metadataTable >+ leap CodeBlock::m_metadata[metadataTable], metadataTable > move TagTypeNumber, tagTypeNumber > addp TagBitTypeOther, tagTypeNumber, tagMask > end >diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >index daaa8a402964918574032d6ee93cba2a27a78a3e..221b118eec30008278f7bbc0cf00146fe484c36b 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >@@ -645,6 +645,15 @@ macro branchIfException(label) > end > > >+macro getMetadata(opcodeID, metadataSize, offset, dst, scratch) >+ getOperand(offset, dst) # metadataID >+ loadp CodeBlock[cfr], scratch # CodeBlock >+ leap CodeBlock::m_metadata[scratch], scratch # CodeBlock->m_metadata >+ loadp opcodeID * 4[scratch], scratch # Array<Op::Metadata> >+ muli metadataSize, dst # offset = sizeof(Op::Metadata) * metadataID >+ leap [dst, scratch], dst # Array<Op::Metadata>[offset] >+end >+ > # Instruction implementations > > _llint_op_enter: >@@ -709,11 +718,12 @@ _llint_op_get_scope: > > _llint_op_to_this: > traceExecution() >- loadi 4[PC], t0 >+ getOperand(1, t0) > bineq TagOffset[cfr, t0, 8], CellTag, .opToThisSlow > loadi PayloadOffset[cfr, t0, 8], t0 > bbneq JSCell::m_type[t0], FinalObjectType, .opToThisSlow >- loadpFromInstruction(2, t2) >+ getMetadata(constexpr op_to_this, sizeof OpToThis::Metadata, 2, t2, t3) >+ loadp OpToThis::Metadata::cachedStructure[t2], t2 > bpneq JSCell::m_structureID[t0], t2, .opToThisSlow > dispatch(constexpr op_to_this_length) > >diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >index ece418d660ce28b1a927d6acd4c23b9f14503eb6..4995c55f223cd8ab54a3d75add2d6187017614ef 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >@@ -593,6 +593,12 @@ macro branchIfException(label) > .noException: > end > >+macro getMetadata(opcodeID, metadataSize, offset, dst, scratch) >+ getOperand(offset, dst) # metadataID >+ loadp opcodeID * 8[metadataTable], scratch # Array<Op::Metadata> >+ muli metadataSize, dst # offset = sizeof(Op::Metadata) * metadataID >+ leap [dst, scratch], dst # Array<Op::Metadata>[offset] >+end > > # Instruction implementations > _llint_op_enter: >@@ -654,12 +660,13 @@ _llint_op_get_scope: > > _llint_op_to_this: > traceExecution() >- loadisFromInstruction(1, t0) >+ getOperand(1, t0) > loadq [cfr, t0, 8], t0 > btqnz t0, tagMask, .opToThisSlow > bbneq JSCell::m_type[t0], FinalObjectType, .opToThisSlow > loadStructureWithScratch(t0, t1, t2, t3) >- loadpFromInstruction(2, t2) >+ getMetadata(constexpr op_to_this, sizeof OpToThis::Metadata, 2, t2, t3) >+ loadp OpToThis::Metadata::cachedStructure[t2], t2 > bpneq t1, t2, .opToThisSlow > dispatch(constexpr op_to_this_length) > >diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >index aa7524d6a361657933ed76a53a2030ab848ac6f0..d7aa0810c0e2a9abe4cf51cf8d14f73e0c1aef8c 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >@@ -60,6 +60,7 @@ > #include "LowLevelInterpreter.h" > #include "MathCommon.h" > #include "ObjectConstructor.h" >+#include "OpToThis.h" > #include "OpcodeInlines.h" > #include "ScopedArguments.h" > #include "StructureRareDataInlines.h" >@@ -262,18 +263,20 @@ SLOW_PATH_DECL(slow_path_create_this) > SLOW_PATH_DECL(slow_path_to_this) > { > BEGIN(); >- JSValue v1 = OP(1).jsValue(); >+ auto bytecode = pc->as<OpToThis>(); >+ auto& metadata = bytecode.metadata(exec); >+ JSValue v1 = exec->uncheckedR(bytecode.srcDst.offset()).jsValue(); > if (v1.isCell()) { > Structure* myStructure = v1.asCell()->structure(vm); >- Structure* otherStructure = pc[2].u.structure.get(); >+ Structure* otherStructure = metadata.cachedStructure.get(); > if (myStructure != otherStructure) { > if (otherStructure) >- pc[3].u.toThisStatus = ToThisConflicted; >- pc[2].u.structure.set(vm, exec->codeBlock(), myStructure); >+ metadata.toThisStatus = ToThisConflicted; >+ metadata.cachedStructure.set(vm, exec->codeBlock(), myStructure); > } > } else { >- pc[3].u.toThisStatus = ToThisConflicted; >- pc[2].u.structure.clear(); >+ metadata.toThisStatus = ToThisConflicted; >+ metadata.cachedStructure.clear(); > } > // Note: We only need to do this value profiling here on the slow path. The fast path > // just returns the input to to_this if the structure check succeeds. If the structure >@@ -281,7 +284,10 @@ SLOW_PATH_DECL(slow_path_to_this) > // different object that still has the same structure on the fast path since it'll produce > // the same SpeculatedType. Therefore, we don't need to worry about value profiling on the > // fast path. >- RETURN_PROFILED(op_to_this, v1.toThis(exec, exec->codeBlock()->isStrictMode() ? StrictMode : NotStrictMode)); >+ auto value = v1.toThis(exec, exec->codeBlock()->isStrictMode() ? StrictMode : NotStrictMode); >+ RETURN_WITH_PROFILING(value, { >+ metadata.profile.m_buckets[0] = JSValue::encode(value); >+ }); > } > > SLOW_PATH_DECL(slow_path_throw_tdz_error)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189785
:
350195
|
350243
|
350276
|
350278
|
350284
|
350287
|
350297
|
350300
|
350301
|
350307
|
350312
|
350316
|
350325
|
350414
|
350432
|
350433
|
350436
|
350437
|
350440
|
350445
|
350465
|
350466
|
350472
|
350473
|
350699
|
350737