Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (189759 => 189760)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2015-09-14 23:44:33 UTC (rev 189760)
@@ -107,7 +107,6 @@
bytecode/PolymorphicAccess.cpp
bytecode/PreciseJumpTargets.cpp
bytecode/PropertyCondition.cpp
- bytecode/PutByIdFlags.cpp
bytecode/PutByIdStatus.cpp
bytecode/PutByIdVariant.cpp
bytecode/ReduceWhitespace.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (189759 => 189760)
--- trunk/Source/_javascript_Core/ChangeLog 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-09-14 23:44:33 UTC (rev 189760)
@@ -1,3 +1,24 @@
+2015-09-14 Commit Queue <commit-qu...@webkit.org>
+
+ Unreviewed, rolling out r189751, r189752, and r189754.
+ https://bugs.webkit.org/show_bug.cgi?id=149143
+
+ caused crashes everywhere (Requested by alexchristensen on
+ #webkit).
+
+ Reverted changesets:
+
+ "LLInt get/put inline caches shouldn't use tons of opcodes"
+ https://bugs.webkit.org/show_bug.cgi?id=149106
+ http://trac.webkit.org/changeset/189751
+
+ "Unreviewed, fix non-x86 LLInt build."
+ http://trac.webkit.org/changeset/189752
+
+ "Unreviewed, really fix non-x86 LLInt build without also
+ breaking everything else."
+ http://trac.webkit.org/changeset/189754
+
2015-09-14 Filip Pizlo <fpi...@apple.com>
Unreviewed, really fix non-x86 LLInt build without also breaking everything else.
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (189759 => 189760)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-09-14 23:44:33 UTC (rev 189760)
@@ -346,7 +346,6 @@
<ClCompile Include="..\bytecode\PolymorphicAccess.cpp" />
<ClCompile Include="..\bytecode\PreciseJumpTargets.cpp" />
<ClCompile Include="..\bytecode\PropertyCondition.cpp" />
- <ClCompile Include="..\bytecode\PutByIdFlags.cpp" />
<ClCompile Include="..\bytecode\PutByIdStatus.cpp" />
<ClCompile Include="..\bytecode\PutByIdVariant.cpp" />
<ClCompile Include="..\bytecode\ReduceWhitespace.cpp" />
@@ -1047,7 +1046,6 @@
<ClInclude Include="..\bytecode\PolymorphicAccess.h" />
<ClInclude Include="..\bytecode\PreciseJumpTargets.h" />
<ClInclude Include="..\bytecode\PropertyCondition.h" />
- <ClInclude Include="..\bytecode\PutByIdFlags.h" />
<ClInclude Include="..\bytecode\PutByIdStatus.h" />
<ClInclude Include="..\bytecode\PutByIdVariant.h" />
<ClInclude Include="..\bytecode\PutKind.h" />
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters (189759 => 189760)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-09-14 23:44:33 UTC (rev 189760)
@@ -201,9 +201,6 @@
<ClCompile Include="..\bytecode\PolymorphicAccess.cpp">
<Filter>bytecode</Filter>
</ClCompile>
- <ClCompile Include="..\bytecode\PutByIdFlags.cpp">
- <Filter>bytecode</Filter>
- </ClCompile>
<ClCompile Include="..\bytecode\PutByIdStatus.cpp">
<Filter>bytecode</Filter>
</ClCompile>
@@ -2097,9 +2094,6 @@
<ClInclude Include="..\bytecode\PolymorphicAccess.h">
<Filter>bytecode</Filter>
</ClInclude>
- <ClInclude Include="..\bytecode\PutByIdFlags.h">
- <Filter>bytecode</Filter>
- </ClInclude>
<ClInclude Include="..\bytecode\PutByIdStatus.h">
<Filter>bytecode</Filter>
</ClInclude>
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (189759 => 189760)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-09-14 23:44:33 UTC (rev 189760)
@@ -105,8 +105,6 @@
0F13912B16771C3A009CCB07 /* ProfilerProfiledBytecodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13912616771C30009CCB07 /* ProfilerProfiledBytecodes.cpp */; };
0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */; };
- 0F15CD221BA5F9860031FFD3 /* PutByIdFlags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F15CD201BA5F9860031FFD3 /* PutByIdFlags.cpp */; };
- 0F15CD231BA5F9860031FFD3 /* PutByIdFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15CD211BA5F9860031FFD3 /* PutByIdFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F1725FF1B48719A00AC3A55 /* DFGMinifiedGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F1725FE1B48719A00AC3A55 /* DFGMinifiedGraph.cpp */; };
0F18D3CF1B55A6E0002C5C9F /* DFGAdaptiveStructureWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F18D3CD1B55A6E0002C5C9F /* DFGAdaptiveStructureWatchpoint.cpp */; };
@@ -1934,8 +1932,6 @@
0F13912616771C30009CCB07 /* ProfilerProfiledBytecodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerProfiledBytecodes.cpp; path = profiler/ProfilerProfiledBytecodes.cpp; sourceTree = "<group>"; };
0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerProfiledBytecodes.h; path = profiler/ProfilerProfiledBytecodes.h; sourceTree = "<group>"; };
0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndexingType.cpp; sourceTree = "<group>"; };
- 0F15CD201BA5F9860031FFD3 /* PutByIdFlags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PutByIdFlags.cpp; sourceTree = "<group>"; };
- 0F15CD211BA5F9860031FFD3 /* PutByIdFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutByIdFlags.h; sourceTree = "<group>"; };
0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
0F1725FE1B48719A00AC3A55 /* DFGMinifiedGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMinifiedGraph.cpp; path = dfg/DFGMinifiedGraph.cpp; sourceTree = "<group>"; };
0F18D3CD1B55A6E0002C5C9F /* DFGAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAdaptiveStructureWatchpoint.cpp; path = dfg/DFGAdaptiveStructureWatchpoint.cpp; sourceTree = "<group>"; };
@@ -5604,8 +5600,6 @@
0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */,
0FD3E4071B618B6600C80E1E /* PropertyCondition.cpp */,
0FD3E4081B618B6600C80E1E /* PropertyCondition.h */,
- 0F15CD201BA5F9860031FFD3 /* PutByIdFlags.cpp */,
- 0F15CD211BA5F9860031FFD3 /* PutByIdFlags.h */,
0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */,
0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */,
0F93B4A718B92C4D00178A3F /* PutByIdVariant.cpp */,
@@ -6746,7 +6740,6 @@
0F682FB319BCB36400FA3BAD /* DFGSSACalculator.h in Headers */,
0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */,
0F2D4DEA19832DAC007D4B19 /* TypeLocation.h in Headers */,
- 0F15CD231BA5F9860031FFD3 /* PutByIdFlags.h in Headers */,
A5BA15E8182340B300A82E69 /* RemoteInspector.h in Headers */,
A5BA15EA182340B400A82E69 /* RemoteInspectorConstants.h in Headers */,
A5BA15F0182345AF00A82E69 /* RemoteInspectorDebuggable.h in Headers */,
@@ -7479,7 +7472,6 @@
0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */,
0F8F2B99172F04FF007DBDA5 /* DFGDesiredIdentifiers.cpp in Sources */,
- 0F15CD221BA5F9860031FFD3 /* PutByIdFlags.cpp in Sources */,
C2C0F7CD17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp in Sources */,
0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */,
C2981FD817BAEE4B00A3BC98 /* DFGDesiredWeakReferences.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeList.json (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/BytecodeList.json 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeList.json 2015-09-14 23:44:33 UTC (rev 189760)
@@ -57,8 +57,14 @@
{ "name" : "op_is_function", "length" : 3 },
{ "name" : "op_in", "length" : 4 },
{ "name" : "op_get_by_id", "length" : 9 },
+ { "name" : "op_get_by_id_out_of_line", "length" : 9 },
{ "name" : "op_get_array_length", "length" : 9 },
{ "name" : "op_put_by_id", "length" : 9 },
+ { "name" : "op_put_by_id_out_of_line", "length" : 9 },
+ { "name" : "op_put_by_id_transition_direct", "length" : 9 },
+ { "name" : "op_put_by_id_transition_direct_out_of_line", "length" : 9 },
+ { "name" : "op_put_by_id_transition_normal", "length" : 9 },
+ { "name" : "op_put_by_id_transition_normal_out_of_line", "length" : 9 },
{ "name" : "op_del_by_id", "length" : 4 },
{ "name" : "op_get_by_val", "length" : 6 },
{ "name" : "op_put_by_val", "length" : 5 },
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2015-09-14 23:44:33 UTC (rev 189760)
@@ -93,6 +93,11 @@
return;
}
case op_put_by_index:
+ case op_put_by_id_transition_direct:
+ case op_put_by_id_transition_direct_out_of_line:
+ case op_put_by_id_transition_normal:
+ case op_put_by_id_transition_normal_out_of_line:
+ case op_put_by_id_out_of_line:
case op_put_by_id:
case op_put_to_scope:
case op_put_to_arguments: {
@@ -129,6 +134,7 @@
case op_get_from_scope:
case op_to_primitive:
case op_get_by_id:
+ case op_get_by_id_out_of_line:
case op_get_array_length:
case op_typeof:
case op_is_undefined:
@@ -271,6 +277,11 @@
case op_switch_char:
case op_switch_string:
case op_put_by_id:
+ case op_put_by_id_out_of_line:
+ case op_put_by_id_transition_direct:
+ case op_put_by_id_transition_direct_out_of_line:
+ case op_put_by_id_transition_normal:
+ case op_put_by_id_transition_normal_out_of_line:
case op_put_getter_by_id:
case op_put_setter_by_id:
case op_put_getter_setter:
@@ -317,6 +328,7 @@
case op_call_eval:
case op_construct:
case op_get_by_id:
+ case op_get_by_id_out_of_line:
case op_get_array_length:
case op_check_has_instance:
case op_instanceof:
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -273,6 +273,9 @@
case op_get_by_id:
op = "get_by_id";
break;
+ case op_get_by_id_out_of_line:
+ op = "get_by_id_out_of_line";
+ break;
case op_get_array_length:
op = "array_length";
break;
@@ -328,8 +331,7 @@
if (exec->interpreter()->getOpcodeID(instruction[0].u.opcode) == op_get_array_length)
out.printf(" llint(array_length)");
- else if (StructureID structureID = instruction[4].u.structureID) {
- Structure* structure = m_vm->heap.structureIDTable().get(structureID);
+ else if (Structure* structure = instruction[4].u.structure.get()) {
out.printf(" llint(");
dumpStructure(out, "struct", structure, ident);
out.printf(")");
@@ -380,31 +382,42 @@
#endif
}
-void CodeBlock::printPutByIdCacheStatus(PrintStream& out, int location, const StubInfoMap& map)
+void CodeBlock::printPutByIdCacheStatus(PrintStream& out, ExecState* exec, int location, const StubInfoMap& map)
{
Instruction* instruction = instructions().begin() + location;
const Identifier& ident = identifier(instruction[2].u.operand);
UNUSED_PARAM(ident); // tell the compiler to shut up in certain platform configurations.
-
- out.print(", ", instruction[8].u.putByIdFlags);
- if (StructureID structureID = instruction[4].u.structureID) {
- Structure* structure = m_vm->heap.structureIDTable().get(structureID);
- out.print(" llint(");
- if (StructureID newStructureID = instruction[6].u.structureID) {
- Structure* newStructure = m_vm->heap.structureIDTable().get(newStructureID);
+ if (Structure* structure = instruction[4].u.structure.get()) {
+ switch (exec->interpreter()->getOpcodeID(instruction[0].u.opcode)) {
+ case op_put_by_id:
+ case op_put_by_id_out_of_line:
+ out.print(" llint(");
+ dumpStructure(out, "struct", structure, ident);
+ out.print(")");
+ break;
+
+ case op_put_by_id_transition_direct:
+ case op_put_by_id_transition_normal:
+ case op_put_by_id_transition_direct_out_of_line:
+ case op_put_by_id_transition_normal_out_of_line:
+ out.print(" llint(");
dumpStructure(out, "prev", structure, ident);
out.print(", ");
- dumpStructure(out, "next", newStructure, ident);
+ dumpStructure(out, "next", instruction[6].u.structure.get(), ident);
if (StructureChain* chain = instruction[7].u.structureChain.get()) {
out.print(", ");
dumpChain(out, chain, ident);
}
- } else
- dumpStructure(out, "struct", structure, ident);
- out.print(")");
+ out.print(")");
+ break;
+
+ default:
+ out.print(" llint(unknown)");
+ break;
+ }
}
#if ENABLE(JIT)
@@ -988,6 +1001,7 @@
break;
}
case op_get_by_id:
+ case op_get_by_id_out_of_line:
case op_get_array_length: {
printGetByIdOp(out, exec, location, it);
printGetByIdCacheStatus(out, exec, location, stubInfos);
@@ -996,9 +1010,34 @@
}
case op_put_by_id: {
printPutByIdOp(out, exec, location, it, "put_by_id");
- printPutByIdCacheStatus(out, location, stubInfos);
+ printPutByIdCacheStatus(out, exec, location, stubInfos);
break;
}
+ case op_put_by_id_out_of_line: {
+ printPutByIdOp(out, exec, location, it, "put_by_id_out_of_line");
+ printPutByIdCacheStatus(out, exec, location, stubInfos);
+ break;
+ }
+ case op_put_by_id_transition_direct: {
+ printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct");
+ printPutByIdCacheStatus(out, exec, location, stubInfos);
+ break;
+ }
+ case op_put_by_id_transition_direct_out_of_line: {
+ printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct_out_of_line");
+ printPutByIdCacheStatus(out, exec, location, stubInfos);
+ break;
+ }
+ case op_put_by_id_transition_normal: {
+ printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal");
+ printPutByIdCacheStatus(out, exec, location, stubInfos);
+ break;
+ }
+ case op_put_by_id_transition_normal_out_of_line: {
+ printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal_out_of_line");
+ printPutByIdCacheStatus(out, exec, location, stubInfos);
+ break;
+ }
case op_put_getter_by_id: {
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
@@ -1897,6 +1936,7 @@
instructions[i + opLength - 1] = profile;
break;
}
+ case op_get_by_id_out_of_line:
case op_get_array_length:
CRASH();
@@ -2377,17 +2417,12 @@
for (size_t i = 0; i < propertyAccessInstructions.size(); ++i) {
Instruction* instruction = &instructions()[propertyAccessInstructions[i]];
switch (interpreter->getOpcodeID(instruction[0].u.opcode)) {
- case op_put_by_id: {
- StructureID oldStructureID = instruction[4].u.structureID;
- StructureID newStructureID = instruction[6].u.structureID;
- if (!oldStructureID || !newStructureID)
- break;
- Structure* oldStructure =
- m_vm->heap.structureIDTable().get(oldStructureID);
- Structure* newStructure =
- m_vm->heap.structureIDTable().get(newStructureID);
- if (Heap::isMarked(oldStructure))
- visitor.appendUnbarrieredReadOnlyPointer(newStructure);
+ case op_put_by_id_transition_direct:
+ case op_put_by_id_transition_normal:
+ case op_put_by_id_transition_direct_out_of_line:
+ case op_put_by_id_transition_normal_out_of_line: {
+ if (Heap::isMarked(instruction[4].u.structure.get()))
+ visitor.append(&instruction[6].u.structure);
else
allAreMarkedSoFar = false;
break;
@@ -2518,32 +2553,36 @@
for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
- case op_get_by_id: {
- StructureID oldStructureID = curInstruction[4].u.structureID;
- if (!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID)))
+ case op_get_by_id:
+ case op_get_by_id_out_of_line:
+ case op_put_by_id:
+ case op_put_by_id_out_of_line:
+ if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get()))
break;
if (Options::verboseOSR())
- dataLogF("Clearing LLInt property access.\n");
- curInstruction[4].u.structureID = 0;
+ dataLogF("Clearing LLInt property access with structure %p.\n", curInstruction[4].u.structure.get());
+ curInstruction[4].u.structure.clear();
curInstruction[5].u.operand = 0;
break;
- }
- case op_put_by_id: {
- StructureID oldStructureID = curInstruction[4].u.structureID;
- StructureID newStructureID = curInstruction[6].u.structureID;
- StructureChain* chain = curInstruction[7].u.structureChain.get();
- if ((!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID))) &&
- (!newStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(newStructureID))) &&
- (!chain || Heap::isMarked(chain)))
+ case op_put_by_id_transition_direct:
+ case op_put_by_id_transition_normal:
+ case op_put_by_id_transition_direct_out_of_line:
+ case op_put_by_id_transition_normal_out_of_line:
+ if (Heap::isMarked(curInstruction[4].u.structure.get())
+ && Heap::isMarked(curInstruction[6].u.structure.get())
+ && Heap::isMarked(curInstruction[7].u.structureChain.get()))
break;
- if (Options::verboseOSR())
- dataLogF("Clearing LLInt put transition.\n");
- curInstruction[4].u.structureID = 0;
- curInstruction[5].u.operand = 0;
- curInstruction[6].u.structureID = 0;
+ if (Options::verboseOSR()) {
+ dataLogF("Clearing LLInt put transition with structures %p -> %p, chain %p.\n",
+ curInstruction[4].u.structure.get(),
+ curInstruction[6].u.structure.get(),
+ curInstruction[7].u.structureChain.get());
+ }
+ curInstruction[4].u.structure.clear();
+ curInstruction[6].u.structure.clear();
curInstruction[7].u.structureChain.clear();
+ curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id);
break;
- }
case op_get_array_length:
break;
case op_to_this:
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2015-09-14 23:44:33 UTC (rev 189760)
@@ -969,7 +969,7 @@
enum CacheDumpMode { DumpCaches, DontDumpCaches };
void printCallOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op, CacheDumpMode, bool& hasPrintedProfiling, const CallLinkInfoMap&);
void printPutByIdOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
- void printPutByIdCacheStatus(PrintStream&, int location, const StubInfoMap&);
+ void printPutByIdCacheStatus(PrintStream&, ExecState*, int location, const StubInfoMap&);
void printLocationAndOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
void printLocationOpAndRegisterOperand(PrintStream&, ExecState*, int location, const Instruction*& it, const char* op, int operand);
Modified: trunk/Source/_javascript_Core/bytecode/GetByIdStatus.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -70,20 +70,15 @@
UNUSED_PARAM(profiledBlock);
UNUSED_PARAM(bytecodeIndex);
UNUSED_PARAM(uid);
-
- VM& vm = *profiledBlock->vm();
-
Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
if (instruction[0].u.opcode == LLInt::getOpcode(op_get_array_length))
return GetByIdStatus(NoInformation, false);
- StructureID structureID = instruction[4].u.structureID;
- if (!structureID)
+ Structure* structure = instruction[4].u.structure.get();
+ if (!structure)
return GetByIdStatus(NoInformation, false);
- Structure* structure = vm.heap.structureIDTable().get(structureID);
-
if (structure->takesSlowPathInDFGForImpureProperty())
return GetByIdStatus(NoInformation, false);
Modified: trunk/Source/_javascript_Core/bytecode/Instruction.h (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/Instruction.h 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/Instruction.h 2015-09-14 23:44:33 UTC (rev 189760)
@@ -32,7 +32,6 @@
#include "BasicBlockLocation.h"
#include "MacroAssembler.h"
#include "Opcode.h"
-#include "PutByIdFlags.h"
#include "SymbolTable.h"
#include "TypeLocation.h"
#include "PropertySlot.h"
@@ -76,11 +75,6 @@
u.operand = operand;
}
- Instruction(PutByIdFlags flags)
- {
- u.putByIdFlags = flags;
- }
-
Instruction(VM& vm, JSCell* owner, Structure* structure)
{
u.structure.clear();
@@ -113,7 +107,6 @@
Opcode opcode;
int operand;
WriteBarrierBase<Structure> structure;
- StructureID structureID;
WriteBarrierBase<SymbolTable> symbolTable;
WriteBarrierBase<StructureChain> structureChain;
WriteBarrierBase<JSCell> jsCell;
@@ -132,7 +125,6 @@
ToThisStatus toThisStatus;
TypeLocation* location;
BasicBlockLocation* basicBlockLocation;
- PutByIdFlags putByIdFlags;
} u;
private:
Deleted: trunk/Source/_javascript_Core/bytecode/PutByIdFlags.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/PutByIdFlags.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/PutByIdFlags.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#include "config.h"
-#include "PutByIdFlags.h"
-
-#include <wtf/CommaPrinter.h>
-#include <wtf/PrintStream.h>
-#include <wtf/StringPrintStream.h>
-
-namespace WTF {
-
-using namespace JSC;
-
-void printInternal(PrintStream& out, PutByIdFlags flags) {
- StringPrintStream stringOut;
- CommaPrinter comma("|");
- if (flags & PutByIdIsDirect)
- stringOut.print(comma, "IsDirect");
-
- CString string = stringOut.toCString();
- if (!string.length())
- out.print("None");
- else
- out.print(string);
-}
-
-} // namespace WTF
-
Deleted: trunk/Source/_javascript_Core/bytecode/PutByIdFlags.h (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/PutByIdFlags.h 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/PutByIdFlags.h 2015-09-14 23:44:33 UTC (rev 189760)
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#ifndef PutByIdFlags_h
-#define PutByIdFlags_h
-
-namespace JSC {
-
-enum PutByIdFlags {
- PutByIdNone = 0,
- PutByIdIsDirect = 1
-};
-
-} // namespace JSC
-
-namespace WTF {
-
-class PrintStream;
-
-void printInternal(PrintStream&, JSC::PutByIdFlags);
-
-} // namespace WTF
-
-#endif // PutByIdFlags_h
-
Modified: trunk/Source/_javascript_Core/bytecode/PutByIdStatus.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/PutByIdStatus.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/PutByIdStatus.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -66,36 +66,37 @@
UNUSED_PARAM(profiledBlock);
UNUSED_PARAM(bytecodeIndex);
UNUSED_PARAM(uid);
-
- VM& vm = *profiledBlock->vm();
-
Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
- StructureID structureID = instruction[4].u.structureID;
- if (!structureID)
+ Structure* structure = instruction[4].u.structure.get();
+ if (!structure)
return PutByIdStatus(NoInformation);
- Structure* structure = vm.heap.structureIDTable().get(structureID);
-
- StructureID newStructureID = instruction[6].u.structureID;
- if (!newStructureID) {
+ if (instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id)
+ || instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id_out_of_line)) {
PropertyOffset offset = structure->getConcurrently(uid);
if (!isValidOffset(offset))
return PutByIdStatus(NoInformation);
return PutByIdVariant::replace(structure, offset);
}
-
- Structure* newStructure = vm.heap.structureIDTable().get(newStructureID);
ASSERT(structure->transitionWatchpointSetHasBeenInvalidated());
+ ASSERT(instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id_transition_direct)
+ || instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id_transition_normal)
+ || instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id_transition_direct_out_of_line)
+ || instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id_transition_normal_out_of_line));
+
+ Structure* newStructure = instruction[6].u.structure.get();
+
PropertyOffset offset = newStructure->getConcurrently(uid);
if (!isValidOffset(offset))
return PutByIdStatus(NoInformation);
ObjectPropertyConditionSet conditionSet;
- if (!(instruction[8].u.putByIdFlags & PutByIdIsDirect)) {
+ if (instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id_transition_normal)
+ || instruction[0].u.opcode == LLInt::getOpcode(op_put_by_id_transition_normal_out_of_line)) {
conditionSet =
generateConditionsForPropertySetterMissConcurrently(
*profiledBlock->vm(), profiledBlock->globalObject(), structure, uid);
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2015-09-14 23:44:33 UTC (rev 189760)
@@ -36,7 +36,6 @@
#include "JSCell.h"
#include "JSString.h"
#include "ParserModes.h"
-#include "PutByIdFlags.h"
#include "RegExp.h"
#include "SpecialPointer.h"
#include "UnlinkedFunctionExecutable.h"
@@ -98,12 +97,10 @@
UnlinkedInstruction() { u.operand = 0; }
UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; }
UnlinkedInstruction(int operand) { u.operand = operand; }
- UnlinkedInstruction(PutByIdFlags flags) { u.putByIdFlags = flags; }
union {
OpcodeID opcode;
int32_t operand;
unsigned index;
- PutByIdFlags putByIdFlags;
} u;
};
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -2103,11 +2103,11 @@
instructions().append(base->index());
instructions().append(propertyIndex);
instructions().append(value->index());
- instructions().append(0); // old structure
- instructions().append(0); // offset
- instructions().append(0); // new structure
- instructions().append(0); // structure chain
- instructions().append(PutByIdNone); // is not direct
+ instructions().append(0);
+ instructions().append(0);
+ instructions().append(0);
+ instructions().append(0);
+ instructions().append(0);
return value;
}
@@ -2125,11 +2125,11 @@
instructions().append(base->index());
instructions().append(propertyIndex);
instructions().append(value->index());
- instructions().append(0); // old structure
- instructions().append(0); // offset
- instructions().append(0); // new structure
- instructions().append(0); // structure chain (unused if direct)
- instructions().append((putType == PropertyNode::KnownDirect || property != m_vm->propertyNames->underscoreProto) ? PutByIdIsDirect : PutByIdNone);
+ instructions().append(0);
+ instructions().append(0);
+ instructions().append(0);
+ instructions().append(0);
+ instructions().append(putType == PropertyNode::KnownDirect || property != m_vm->propertyNames->underscoreProto);
return value;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -44,7 +44,6 @@
#include "JSCInlines.h"
#include "JSModuleEnvironment.h"
#include "PreciseJumpTargets.h"
-#include "PutByIdFlags.h"
#include "PutByIdStatus.h"
#include "StackAlignment.h"
#include "StringConstructor.h"
@@ -3514,6 +3513,7 @@
}
case op_get_by_id:
+ case op_get_by_id_out_of_line:
case op_get_array_length: {
SpeculatedType prediction = getPrediction();
@@ -3531,11 +3531,16 @@
NEXT_OPCODE(op_get_by_id);
}
- case op_put_by_id: {
+ case op_put_by_id:
+ case op_put_by_id_out_of_line:
+ case op_put_by_id_transition_direct:
+ case op_put_by_id_transition_normal:
+ case op_put_by_id_transition_direct_out_of_line:
+ case op_put_by_id_transition_normal_out_of_line: {
Node* value = get(VirtualRegister(currentInstruction[3].u.operand));
Node* base = get(VirtualRegister(currentInstruction[1].u.operand));
unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
- bool direct = currentInstruction[8].u.putByIdFlags & PutByIdIsDirect;
+ bool direct = currentInstruction[8].u.operand;
PutByIdStatus putByIdStatus = PutByIdStatus::computeFor(
m_inlineStackTop->m_profiledBlock, m_dfgCodeBlock,
Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -152,8 +152,14 @@
case op_put_by_val:
case op_put_by_val_direct:
case op_get_by_id:
+ case op_get_by_id_out_of_line:
case op_get_array_length:
case op_put_by_id:
+ case op_put_by_id_out_of_line:
+ case op_put_by_id_transition_direct:
+ case op_put_by_id_transition_direct_out_of_line:
+ case op_put_by_id_transition_normal:
+ case op_put_by_id_transition_normal_out_of_line:
case op_jmp:
case op_jtrue:
case op_jfalse:
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -217,6 +217,7 @@
DEFINE_OP(op_load_arrowfunction_this)
DEFINE_OP(op_eq)
DEFINE_OP(op_eq_null)
+ case op_get_by_id_out_of_line:
case op_get_array_length:
DEFINE_OP(op_get_by_id)
DEFINE_OP(op_get_by_val)
@@ -268,6 +269,11 @@
DEFINE_OP(op_push_with_scope)
DEFINE_OP(op_create_lexical_environment)
DEFINE_OP(op_get_parent_scope)
+ case op_put_by_id_out_of_line:
+ case op_put_by_id_transition_direct:
+ case op_put_by_id_transition_normal:
+ case op_put_by_id_transition_direct_out_of_line:
+ case op_put_by_id_transition_normal_out_of_line:
DEFINE_OP(op_put_by_id)
DEFINE_OP(op_put_by_index)
case op_put_by_val_direct:
@@ -380,6 +386,7 @@
DEFINE_SLOWCASE_OP(op_create_this)
DEFINE_SLOWCASE_OP(op_div)
DEFINE_SLOWCASE_OP(op_eq)
+ case op_get_by_id_out_of_line:
case op_get_array_length:
DEFINE_SLOWCASE_OP(op_get_by_id)
DEFINE_SLOWCASE_OP(op_get_by_val)
@@ -406,6 +413,11 @@
DEFINE_SLOWCASE_OP(op_nstricteq)
DEFINE_SLOWCASE_OP(op_dec)
DEFINE_SLOWCASE_OP(op_inc)
+ case op_put_by_id_out_of_line:
+ case op_put_by_id_transition_direct:
+ case op_put_by_id_transition_normal:
+ case op_put_by_id_transition_direct_out_of_line:
+ case op_put_by_id_transition_normal_out_of_line:
DEFINE_SLOWCASE_OP(op_put_by_id)
case op_put_by_val_direct:
DEFINE_SLOWCASE_OP(op_put_by_val)
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -607,7 +607,7 @@
{
int baseVReg = currentInstruction[1].u.operand;
int valueVReg = currentInstruction[3].u.operand;
- unsigned direct = currentInstruction[8].u.putByIdFlags & PutByIdIsDirect;
+ unsigned direct = currentInstruction[8].u.operand;
emitWriteBarrier(baseVReg, valueVReg, ShouldFilterBase);
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -623,7 +623,7 @@
int base = currentInstruction[1].u.operand;
int value = currentInstruction[3].u.operand;
- int direct = currentInstruction[8].u.putByIdFlags & PutByIdIsDirect;
+ int direct = currentInstruction[8].u.operand;
emitWriteBarrier(base, value, ShouldFilterBase);
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (189759 => 189760)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2015-09-14 23:44:33 UTC (rev 189760)
@@ -570,20 +570,20 @@
JSCell* baseCell = baseValue.asCell();
Structure* structure = baseCell->structure();
- // Start out by clearing out the old cache.
- pc[0].u.opcode = LLInt::getOpcode(op_get_by_id);
- pc[4].u.pointer = nullptr; // old structure
- pc[5].u.pointer = nullptr; // offset
-
if (!structure->isUncacheableDictionary()
&& !structure->typeInfo().prohibitsPropertyCaching()
&& !structure->typeInfo().newImpurePropertyFiresWatchpoints()) {
- vm.heap.writeBarrier(codeBlock->ownerExecutable());
-
ConcurrentJITLocker locker(codeBlock->m_lock);
- pc[4].u.structureID = structure->id();
- pc[5].u.operand = slot.cachedOffset();
+ pc[4].u.structure.set(
+ vm, codeBlock->ownerExecutable(), structure);
+ if (isInlineOffset(slot.cachedOffset())) {
+ pc[0].u.opcode = LLInt::getOpcode(op_get_by_id);
+ pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
+ } else {
+ pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_out_of_line);
+ pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
+ }
}
}
@@ -618,7 +618,7 @@
JSValue baseValue = LLINT_OP_C(1).jsValue();
PutPropertySlot slot(baseValue, codeBlock->isStrictMode(), codeBlock->putByIdContext());
- if (pc[8].u.putByIdFlags & PutByIdIsDirect)
+ if (pc[8].u.operand)
asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
else
baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
@@ -627,12 +627,6 @@
if (!LLINT_ALWAYS_ACCESS_SLOW
&& baseValue.isCell()
&& slot.isCacheablePut()) {
-
- // Start out by clearing out the old cache.
- pc[4].u.pointer = nullptr; // old structure
- pc[5].u.pointer = nullptr; // offset
- pc[6].u.pointer = nullptr; // new structure
- pc[7].u.pointer = nullptr; // structure chain
JSCell* baseCell = baseValue.asCell();
Structure* structure = baseCell->structure();
@@ -640,32 +634,56 @@
if (!structure->isUncacheableDictionary()
&& !structure->typeInfo().prohibitsPropertyCaching()
&& baseCell == slot.base()) {
-
- vm.heap.writeBarrier(codeBlock->ownerExecutable());
if (slot.type() == PutPropertySlot::NewProperty) {
GCSafeConcurrentJITLocker locker(codeBlock->m_lock, vm.heap);
if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
+
+ // This is needed because some of the methods we call
+ // below may GC.
+ pc[0].u.opcode = LLInt::getOpcode(op_put_by_id);
if (normalizePrototypeChain(exec, structure) != InvalidPrototypeChain) {
ASSERT(structure->previousID()->isObject());
- pc[4].u.structureID = structure->previousID()->id();
- pc[5].u.operand = slot.cachedOffset();
- pc[6].u.structureID = structure->id();
- if (!(pc[8].u.putByIdFlags & PutByIdIsDirect)) {
- StructureChain* chain = structure->prototypeChain(exec);
- ASSERT(chain);
- pc[7].u.structureChain.set(
- vm, codeBlock->ownerExecutable(), chain);
+ pc[4].u.structure.set(
+ vm, codeBlock->ownerExecutable(), structure->previousID());
+ if (isInlineOffset(slot.cachedOffset()))
+ pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
+ else
+ pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
+ pc[6].u.structure.set(
+ vm, codeBlock->ownerExecutable(), structure);
+ StructureChain* chain = structure->prototypeChain(exec);
+ ASSERT(chain);
+ pc[7].u.structureChain.set(
+ vm, codeBlock->ownerExecutable(), chain);
+
+ if (pc[8].u.operand) {
+ if (isInlineOffset(slot.cachedOffset()))
+ pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_direct);
+ else
+ pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_direct_out_of_line);
+ } else {
+ if (isInlineOffset(slot.cachedOffset()))
+ pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_normal);
+ else
+ pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_normal_out_of_line);
}
}
}
} else {
structure->didCachePropertyReplacement(vm, slot.cachedOffset());
- pc[4].u.structureID = structure->id();
- pc[5].u.operand = slot.cachedOffset();
+ pc[4].u.structure.set(
+ vm, codeBlock->ownerExecutable(), structure);
+ if (isInlineOffset(slot.cachedOffset())) {
+ pc[0].u.opcode = LLInt::getOpcode(op_put_by_id);
+ pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
+ } else {
+ pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_out_of_line);
+ pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
+ }
}
}
}
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (189759 => 189760)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2015-09-14 23:44:33 UTC (rev 189760)
@@ -1323,25 +1323,39 @@
# to take fast path on the new cache. At worst we take slow path, which is what
# we would have been doing anyway.
-_llint_op_get_by_id:
+macro getById(getPropertyStorage)
traceExecution()
loadi 8[PC], t0
loadi 16[PC], t1
loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdSlow)
loadi 20[PC], t2
- bineq JSCell::m_structureID[t3], t1, .opGetByIdSlow
- loadPropertyAtVariableOffset(t2, t3, t0, t1)
- loadi 4[PC], t2
- storei t0, TagOffset[cfr, t2, 8]
- storei t1, PayloadOffset[cfr, t2, 8]
- valueProfile(t0, t1, 32, t2)
- dispatch(9)
+ getPropertyStorage(
+ t3,
+ t0,
+ macro (propertyStorage, scratch)
+ bpneq JSCell::m_structureID[t3], t1, .opGetByIdSlow
+ loadi 4[PC], t1
+ loadi TagOffset[propertyStorage, t2], scratch
+ loadi PayloadOffset[propertyStorage, t2], t2
+ storei scratch, TagOffset[cfr, t1, 8]
+ storei t2, PayloadOffset[cfr, t1, 8]
+ valueProfile(scratch, t2, 32, t1)
+ dispatch(9)
+ end)
-.opGetByIdSlow:
- callSlowPath(_llint_slow_path_get_by_id)
- dispatch(9)
+ .opGetByIdSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(9)
+end
+_llint_op_get_by_id:
+ getById(withInlineStorage)
+
+_llint_op_get_by_id_out_of_line:
+ getById(withOutOfLineStorage)
+
+
_llint_op_get_array_length:
traceExecution()
loadi 8[PC], t0
@@ -1365,59 +1379,102 @@
dispatch(9)
-_llint_op_put_by_id:
+macro putById(getPropertyStorage)
traceExecution()
writeBarrierOnOperands(1, 3)
loadi 4[PC], t3
+ loadi 16[PC], t1
loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
- loadi JSCell::m_structureID[t0], t2
- bineq t2, 16[PC], .opPutByIdSlow
+ loadi 12[PC], t2
+ getPropertyStorage(
+ t0,
+ t3,
+ macro (propertyStorage, scratch)
+ bpneq JSCell::m_structureID[t0], t1, .opPutByIdSlow
+ loadi 20[PC], t1
+ loadConstantOrVariable2Reg(t2, scratch, t2)
+ storei scratch, TagOffset[propertyStorage, t1]
+ storei t2, PayloadOffset[propertyStorage, t1]
+ dispatch(9)
+ end)
- # At this point, we have:
- # t2 -> currentStructureID
- # t0 -> object base
+ .opPutByIdSlow:
+ callSlowPath(_llint_slow_path_put_by_id)
+ dispatch(9)
+end
- loadi 24[PC], t1
+_llint_op_put_by_id:
+ putById(withInlineStorage)
- btiz t1, .opPutByIdNotTransition
- # This is the transition case. t1 holds the new Structure*. t2 holds the old Structure*.
- # If we have a chain, we need to check it. t0 is the base. We may clobber t1 to use it as
- # scratch.
- loadp 28[PC], t3
- btpz t3, .opPutByIdTransitionDirect
+_llint_op_put_by_id_out_of_line:
+ putById(withOutOfLineStorage)
- loadp StructureChain::m_vector[t3], t3
- assert(macro (ok) btpnz t3, ok end)
- loadp Structure::m_prototype[t2], t2
- btpz t2, .opPutByIdTransitionChainDone
-.opPutByIdTransitionChainLoop:
- loadp [t3], t1
- bpneq t1, JSCell::m_structureID[t2], .opPutByIdSlow
- addp 4, t3
- loadp Structure::m_prototype[t1], t2
- btpnz t2, .opPutByIdTransitionChainLoop
+macro putByIdTransition(additionalChecks, getPropertyStorage)
+ traceExecution()
+ writeBarrierOnOperand(1)
+ loadi 4[PC], t3
+ loadi 16[PC], t1
+ loadConstantOrVariablePayload(t3, CellTag, t0, .opPutByIdSlow)
+ loadi 12[PC], t2
+ bpneq JSCell::m_structureID[t0], t1, .opPutByIdSlow
+ additionalChecks(t1, t3, .opPutByIdSlow)
+ loadi 20[PC], t1
+ getPropertyStorage(
+ t0,
+ t3,
+ macro (propertyStorage, scratch)
+ addp t1, propertyStorage, t3
+ loadConstantOrVariable2Reg(t2, t1, t2)
+ storei t1, TagOffset[t3]
+ loadi 24[PC], t1
+ storei t2, PayloadOffset[t3]
+ storep t1, JSCell::m_structureID[t0]
+ dispatch(9)
+ end)
-.opPutByIdTransitionChainDone:
- loadi 24[PC], t1
+ .opPutByIdSlow:
+ callSlowPath(_llint_slow_path_put_by_id)
+ dispatch(9)
+end
-.opPutByIdTransitionDirect:
- storei t1, JSCell::m_structureID[t0]
+macro noAdditionalChecks(oldStructure, scratch, slowPath)
+end
-.opPutByIdNotTransition:
- # The only thing live right now is t0, which holds the base.
- loadi 12[PC], t1
- loadConstantOrVariable(t1, t2, t3)
- loadi 20[PC], t1
- storePropertyAtVariableOffset(t1, t0, t2, t3)
- dispatch(9)
+macro structureChainChecks(oldStructure, scratch, slowPath)
+ const protoCell = oldStructure # Reusing the oldStructure register for the proto
-.opPutByIdSlow:
- callSlowPath(_llint_slow_path_put_by_id)
- dispatch(9)
+ loadp 28[PC], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ loadp StructureChain::m_vector[scratch], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ bieq Structure::m_prototype + TagOffset[oldStructure], NullTag, .done
+.loop:
+ loadi Structure::m_prototype + PayloadOffset[oldStructure], protoCell
+ loadp JSCell::m_structureID[protoCell], oldStructure
+ bpneq oldStructure, [scratch], slowPath
+ addp 4, scratch
+ bineq Structure::m_prototype + TagOffset[oldStructure], NullTag, .loop
+.done:
+end
+_llint_op_put_by_id_transition_direct:
+ putByIdTransition(noAdditionalChecks, withInlineStorage)
+
+_llint_op_put_by_id_transition_direct_out_of_line:
+ putByIdTransition(noAdditionalChecks, withOutOfLineStorage)
+
+
+_llint_op_put_by_id_transition_normal:
+ putByIdTransition(structureChainChecks, withInlineStorage)
+
+
+_llint_op_put_by_id_transition_normal_out_of_line:
+ putByIdTransition(structureChainChecks, withOutOfLineStorage)
+
+
_llint_op_get_by_val:
traceExecution()
loadi 8[PC], t2
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (189759 => 189760)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2015-09-14 23:40:07 UTC (rev 189759)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2015-09-14 23:44:33 UTC (rev 189760)
@@ -468,16 +468,15 @@
storeq value, ValueProfile::m_buckets[scratch]
end
-macro structureIDToStructureWithScratch(structureIDThenStructure, scratch)
+macro loadStructure(cell, structure)
+end
+
+macro loadStructureWithScratch(cell, structure, scratch)
loadp CodeBlock[cfr], scratch
loadp CodeBlock::m_vm[scratch], scratch
loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[scratch], scratch
- loadp [scratch, structureIDThenStructure, 8], structureIDThenStructure
-end
-
-macro loadStructureWithScratch(cell, structure, scratch)
loadi JSCell::m_structureID[cell], structure
- structureIDToStructureWithScratch(structure, scratch)
+ loadp [scratch, structure, 8], structure
end
macro loadStructureAndClobberFirstArg(cell, structure)
@@ -1205,25 +1204,43 @@
storeq value, (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8]
end
-_llint_op_get_by_id:
+macro getById(getPropertyStorage)
traceExecution()
+ # We only do monomorphic get_by_id caching for now, and we do not modify the
+ # opcode. We do, however, allow for the cache to change anytime if fails, since
+ # ping-ponging is free. At best we get lucky and the get_by_id will continue
+ # to take fast path on the new cache. At worst we take slow path, which is what
+ # we would have been doing anyway.
loadisFromInstruction(2, t0)
loadConstantOrVariableCell(t0, t3, .opGetByIdSlow)
- loadi JSCell::m_structureID[t3], t1
- loadisFromInstruction(4, t2)
- bineq t2, t1, .opGetByIdSlow
- loadisFromInstruction(5, t1)
- loadisFromInstruction(1, t2)
- loadPropertyAtVariableOffset(t1, t3, t0)
- storeq t0, [cfr, t2, 8]
- valueProfile(t0, 8, t1)
- dispatch(9)
+ loadStructureWithScratch(t3, t2, t1)
+ loadpFromInstruction(4, t1)
+ bpneq t2, t1, .opGetByIdSlow
+ getPropertyStorage(
+ t3,
+ t0,
+ macro (propertyStorage, scratch)
+ loadisFromInstruction(5, t2)
+ loadisFromInstruction(1, t1)
+ loadq [propertyStorage, t2], scratch
+ storeq scratch, [cfr, t1, 8]
+ valueProfile(scratch, 8, t1)
+ dispatch(9)
+ end)
+
+ .opGetByIdSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(9)
+end
-.opGetByIdSlow:
- callSlowPath(_llint_slow_path_get_by_id)
- dispatch(9)
+_llint_op_get_by_id:
+ getById(withInlineStorage)
+_llint_op_get_by_id_out_of_line:
+ getById(withOutOfLineStorage)
+
+
_llint_op_get_array_length:
traceExecution()
loadisFromInstruction(2, t0)
@@ -1247,67 +1264,99 @@
dispatch(9)
-_llint_op_put_by_id:
+macro putById(getPropertyStorage)
traceExecution()
writeBarrierOnOperands(1, 3)
loadisFromInstruction(1, t3)
loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
- loadi JSCell::m_structureID[t0], t2
- loadisFromInstruction(4, t1)
- bineq t2, t1, .opPutByIdSlow
+ loadStructureWithScratch(t0, t2, t1)
+ loadpFromInstruction(4, t1)
+ bpneq t2, t1, .opPutByIdSlow
+ getPropertyStorage(
+ t0,
+ t3,
+ macro (propertyStorage, scratch)
+ loadisFromInstruction(5, t1)
+ loadisFromInstruction(3, t2)
+ loadConstantOrVariable(t2, scratch)
+ storeq scratch, [propertyStorage, t1]
+ dispatch(9)
+ end)
+end
- # At this point, we have:
- # t1, t2 -> current structure ID
- # t0 -> object base
+_llint_op_put_by_id:
+ putById(withInlineStorage)
- loadisFromInstruction(6, t1)
-
- btiz t1, .opPutByIdNotTransition
+.opPutByIdSlow:
+ callSlowPath(_llint_slow_path_put_by_id)
+ dispatch(9)
- # This is the transition case. t1 holds the new structureID. t2 holds the old structure ID.
- # If we have a chain, we need to check it. t0 is the base. We may clobber t1 to use it as
- # scratch.
- loadpFromInstruction(7, t3)
- btpz t3, .opPutByIdTransitionDirect
- loadp StructureChain::m_vector[t3], t3
- assert(macro (ok) btpnz t3, ok end)
+_llint_op_put_by_id_out_of_line:
+ putById(withOutOfLineStorage)
- structureIDToStructureWithScratch(t2, t1)
- loadq Structure::m_prototype[t2], t2
- bqeq t2, ValueNull, .opPutByIdTransitionChainDone
-.opPutByIdTransitionChainLoop:
- # At this point, t2 contains a prototye, and [t3] contains the Structure* that we want that
- # prototype to have. We don't want to have to load the Structure* for t2. Instead, we load
- # the Structure* from [t3], and then we compare its id to the id in the header of t2.
- loadp [t3], t1
- loadi JSCell::m_structureID[t2], t2
- # Now, t1 has the Structure* and t2 has the StructureID that we want that Structure* to have.
- bineq t2, Structure::m_blob + StructureIDBlob::u.fields.structureID[t1], .opPutByIdSlow
- addp 8, t3
- loadq Structure::m_prototype[t1], t2
- bqneq t2, ValueNull, .opPutByIdTransitionChainLoop
-.opPutByIdTransitionChainDone:
- # Reload the new structure, since we clobbered it above.
- loadisFromInstruction(6, t1)
+macro putByIdTransition(additionalChecks, getPropertyStorage)
+ traceExecution()
+ writeBarrierOnOperand(1)
+ loadisFromInstruction(1, t3)
+ loadpFromInstruction(4, t1)
+ loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
+ loadStructureWithScratch(t0, t2, t3)
+ bpneq t2, t1, .opPutByIdSlow
+ additionalChecks(t1, t3, t2)
+ loadisFromInstruction(3, t2)
+ loadisFromInstruction(5, t1)
+ getPropertyStorage(
+ t0,
+ t3,
+ macro (propertyStorage, scratch)
+ addp t1, propertyStorage, t3
+ loadConstantOrVariable(t2, t1)
+ storeq t1, [t3]
+ loadpFromInstruction(6, t1)
+ loadi Structure::m_blob + StructureIDBlob::u.words.word1[t1], t1
+ storei t1, JSCell::m_structureID[t0]
+ dispatch(9)
+ end)
+end
-.opPutByIdTransitionDirect:
- storei t1, JSCell::m_structureID[t0]
+macro noAdditionalChecks(oldStructure, scratch, scratch2)
+end
-.opPutByIdNotTransition:
- # The only thing live right now is t0, which holds the base.
- loadisFromInstruction(3, t1)
- loadConstantOrVariable(t1, t2)
- loadisFromInstruction(5, t1)
- storePropertyAtVariableOffset(t1, t0, t2)
- dispatch(9)
+macro structureChainChecks(oldStructure, scratch, scratch2)
+ const protoCell = oldStructure # Reusing the oldStructure register for the proto
+ loadpFromInstruction(7, scratch)
+ assert(macro (ok) btpnz scratch, ok end)
+ loadp StructureChain::m_vector[scratch], scratch
+ assert(macro (ok) btpnz scratch, ok end)
+ bqeq Structure::m_prototype[oldStructure], ValueNull, .done
+.loop:
+ loadq Structure::m_prototype[oldStructure], protoCell
+ loadStructureAndClobberFirstArg(protoCell, scratch2)
+ move scratch2, oldStructure
+ bpneq oldStructure, [scratch], .opPutByIdSlow
+ addp 8, scratch
+ bqneq Structure::m_prototype[oldStructure], ValueNull, .loop
+.done:
+end
-.opPutByIdSlow:
- callSlowPath(_llint_slow_path_put_by_id)
- dispatch(9)
+_llint_op_put_by_id_transition_direct:
+ putByIdTransition(noAdditionalChecks, withInlineStorage)
+_llint_op_put_by_id_transition_direct_out_of_line:
+ putByIdTransition(noAdditionalChecks, withOutOfLineStorage)
+
+
+_llint_op_put_by_id_transition_normal:
+ putByIdTransition(structureChainChecks, withInlineStorage)
+
+
+_llint_op_put_by_id_transition_normal_out_of_line:
+ putByIdTransition(structureChainChecks, withOutOfLineStorage)
+
+
_llint_op_get_by_val:
traceExecution()
loadisFromInstruction(2, t2)