Diff
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/CMakeLists.txt (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/CMakeLists.txt 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/CMakeLists.txt 2018-05-17 05:11:20 UTC (rev 231887)
@@ -455,6 +455,7 @@
bytecode/InternalFunctionAllocationProfile.h
bytecode/JumpTable.h
bytecode/LLIntCallLinkInfo.h
+ bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h
bytecode/LazyOperandValueProfile.h
bytecode/ObjectAllocationProfile.h
bytecode/ObjectPropertyCondition.h
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/ChangeLog (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/ChangeLog 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/ChangeLog 2018-05-17 05:11:20 UTC (rev 231887)
@@ -1,3 +1,41 @@
+2018-05-16 Babak Shafiei <bshaf...@apple.com>
+
+ Cherry-pick r231719. rdar://problem/40054982
+
+ Unreviewed, rolling out r231316 and r231332.
+ https://bugs.webkit.org/show_bug.cgi?id=185564
+
+ Appears to be a Speedometer2/MotionMark regression (Requested
+ by keith_miller on #webkit).
+
+ Reverted changesets:
+
+ "Remove the prototype caching for get_by_id in the LLInt"
+ https://bugs.webkit.org/show_bug.cgi?id=185226
+ https://trac.webkit.org/changeset/231316
+
+ "Unreviewed, fix 32-bit profile offset for change in bytecode"
+ https://trac.webkit.org/changeset/231332
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231719 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2018-05-11 Commit Queue <commit-qu...@webkit.org>
+
+ Unreviewed, rolling out r231316 and r231332.
+ https://bugs.webkit.org/show_bug.cgi?id=185564
+
+ Appears to be a Speedometer2/MotionMark regression (Requested
+ by keith_miller on #webkit).
+
+ Reverted changesets:
+
+ "Remove the prototype caching for get_by_id in the LLInt"
+ https://bugs.webkit.org/show_bug.cgi?id=185226
+ https://trac.webkit.org/changeset/231316
+
+ "Unreviewed, fix 32-bit profile offset for change in bytecode"
+ https://trac.webkit.org/changeset/231332
+
2018-05-09 Kocsen Chung <kocsen_ch...@apple.com>
Cherry-pick r231589. rdar://problem/39999414
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2018-05-17 05:11:20 UTC (rev 231887)
@@ -1037,6 +1037,7 @@
53F40E951D5A7AEF0099A1B6 /* WasmModuleParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E941D5A7AEF0099A1B6 /* WasmModuleParser.h */; };
53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
53F8D2001E8387D400D21116 /* WasmBBQPlanInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F8D1FF1E8387D400D21116 /* WasmBBQPlanInlines.h */; };
+ 53FA2AE11CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
53FD04D41D7AB291003287D3 /* WasmCallingConvention.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FD04D21D7AB187003287D3 /* WasmCallingConvention.h */; settings = {ATTRIBUTES = (Private, ); }; };
53FF7F991DBFCD9000A26CCC /* WasmValidate.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FF7F981DBFCD9000A26CCC /* WasmValidate.h */; };
5B70CFDE1DB69E6600EC23F9 /* JSAsyncFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B70CFD81DB69E5C00EC23F9 /* JSAsyncFunction.h */; };
@@ -3463,6 +3464,8 @@
53F40E961D5A7BEC0099A1B6 /* WasmModuleParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmModuleParser.cpp; sourceTree = "<group>"; };
53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = "<group>"; };
53F8D1FF1E8387D400D21116 /* WasmBBQPlanInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmBBQPlanInlines.h; sourceTree = "<group>"; };
+ 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.h; sourceTree = "<group>"; };
+ 53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp; sourceTree = "<group>"; };
53FD04D11D7AB187003287D3 /* WasmCallingConvention.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmCallingConvention.cpp; sourceTree = "<group>"; };
53FD04D21D7AB187003287D3 /* WasmCallingConvention.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmCallingConvention.h; sourceTree = "<group>"; };
53FF7F981DBFCD9000A26CCC /* WasmValidate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmValidate.h; sourceTree = "<group>"; };
@@ -6674,7 +6677,6 @@
865A30F0135007E100CDB49E /* JSCJSValueInlines.h */,
FE2B0B681FD0D2970075DA5F /* JSCPoison.cpp */,
FE2B0B701FD8C4630075DA5F /* JSCPoison.h */,
- FE7497E5209001B00003565B /* JSCPtrTag.h */,
72AAF7CB1D0D318B005E60BE /* JSCustomGetterSetterFunction.cpp */,
72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */,
0F2B66BD17B6B5AB00A7AE3F /* JSDataView.cpp */,
@@ -6760,6 +6762,7 @@
2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */,
862553CE16136AA5009F17D0 /* JSProxy.cpp */,
862553CF16136AA5009F17D0 /* JSProxy.h */,
+ FE7497E5209001B00003565B /* JSCPtrTag.h */,
534638721E70D01500F12AC1 /* JSRunLoopTimer.cpp */,
534638701E70CF3D00F12AC1 /* JSRunLoopTimer.h */,
14874AE115EBDE4A002E3587 /* JSScope.cpp */,
@@ -7642,6 +7645,8 @@
0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */,
0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */,
0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */,
+ 53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */,
+ 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */,
0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */,
0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */,
20ECB15EFC524624BC2F02D5 /* ModuleNamespaceAccessCase.cpp */,
@@ -9008,7 +9013,6 @@
A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
FE2B0B731FD9EF700075DA5F /* JSCPoison.h in Headers */,
- FE7497E6209001B10003565B /* JSCPtrTag.h in Headers */,
A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
72AAF7CE1D0D31B3005E60BE /* JSCustomGetterSetterFunction.h in Headers */,
0F2B66EC17B6B5AB00A7AE3F /* JSDataView.h in Headers */,
@@ -9085,6 +9089,7 @@
7C008CDB187124BB00955C24 /* JSPromiseDeferred.h in Headers */,
7C184E1F17BEE22E007CB63A /* JSPromisePrototype.h in Headers */,
996B731F1BDA08EF00331B84 /* JSPromisePrototype.lut.h in Headers */,
+ FE7497E6209001B10003565B /* JSCPtrTag.h in Headers */,
2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */,
862553D216136E1A009F17D0 /* JSProxy.h in Headers */,
A552C3801ADDB8FE00139726 /* JSRemoteInspector.h in Headers */,
@@ -9173,6 +9178,7 @@
0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */,
FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */,
79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */,
+ 53FA2AE11CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h in Headers */,
0F4680A514BA7F8D00BFE272 /* LLIntSlowPaths.h in Headers */,
0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
0F75A061200D26180038E2CF /* LocalAllocator.h in Headers */,
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/Sources.txt (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/Sources.txt 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/Sources.txt 2018-05-17 05:11:20 UTC (rev 231887)
@@ -224,6 +224,7 @@
bytecode/InlineCallFrameSet.cpp
bytecode/IntrinsicGetterAccessCase.cpp
bytecode/JumpTable.cpp
+bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp
bytecode/LazyOperandValueProfile.cpp
bytecode/MethodOfGettingAValueProfile.cpp
bytecode/ModuleNamespaceAccessCase.cpp
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/BytecodeDumper.cpp (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2018-05-17 05:11:20 UTC (rev 231887)
@@ -377,6 +377,12 @@
case op_get_by_id:
op = "get_by_id";
break;
+ case op_get_by_id_proto_load:
+ op = "get_by_id_proto_load";
+ break;
+ case op_get_by_id_unset:
+ op = "get_by_id_unset";
+ break;
case op_get_array_length:
op = "array_length";
break;
@@ -391,7 +397,7 @@
int id0 = (++it)->u.operand;
printLocationAndOp(out, location, it, op);
out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data());
- it += 3; // Increment up to the value profiler.
+ it += 4; // Increment up to the value profiler.
}
static void dumpStructure(PrintStream& out, const char* name, Structure* structure, const Identifier& ident)
@@ -436,6 +442,8 @@
out.printf(" llint(");
dumpStructure(out, "struct", structure, ident);
out.printf(")");
+ if (Interpreter::getOpcodeID(instruction[0]) == op_get_by_id_proto_load)
+ out.printf(" proto(%p)", getPointer(instruction[6]));
}
#if ENABLE(JIT)
@@ -1030,6 +1038,8 @@
break;
}
case op_get_by_id:
+ case op_get_by_id_proto_load:
+ case op_get_by_id_unset:
case op_get_array_length: {
printGetByIdOp(out, location, it);
printGetByIdCacheStatus(out, location, stubInfos);
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/BytecodeList.json (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/BytecodeList.json 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/BytecodeList.json 2018-05-17 05:11:20 UTC (rev 231887)
@@ -81,8 +81,10 @@
{ "name" : "op_is_function", "length" : 3 },
{ "name" : "op_is_cell_with_type", "length" : 4 },
{ "name" : "op_in", "length" : 5 },
- { "name" : "op_get_array_length", "length" : 8 },
- { "name" : "op_get_by_id", "length" : 8 },
+ { "name" : "op_get_array_length", "length" : 9 },
+ { "name" : "op_get_by_id", "length" : 9 },
+ { "name" : "op_get_by_id_proto_load", "length" : 9 },
+ { "name" : "op_get_by_id_unset", "length" : 9 },
{ "name" : "op_get_by_id_with_this", "length" : 6 },
{ "name" : "op_get_by_val_with_this", "length" : 6 },
{ "name" : "op_get_by_id_direct", "length" : 7 },
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/BytecodeUseDef.h (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2018-05-17 05:11:20 UTC (rev 231887)
@@ -182,6 +182,8 @@
case op_to_primitive:
case op_try_get_by_id:
case op_get_by_id:
+ case op_get_by_id_proto_load:
+ case op_get_by_id_unset:
case op_get_by_id_direct:
case op_get_array_length:
case op_typeof:
@@ -432,6 +434,8 @@
case op_construct:
case op_try_get_by_id:
case op_get_by_id:
+ case op_get_by_id_proto_load:
+ case op_get_by_id_unset:
case op_get_by_id_direct:
case op_get_by_id_with_this:
case op_get_by_val_with_this:
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/CodeBlock.cpp (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/CodeBlock.cpp 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/CodeBlock.cpp 2018-05-17 05:11:20 UTC (rev 231887)
@@ -65,6 +65,7 @@
#include "JSTemplateObjectDescriptor.h"
#include "LLIntData.h"
#include "LLIntEntrypoint.h"
+#include "LLIntPrototypeLoadAdaptiveStructureWatchpoint.h"
#include "LowLevelInterpreter.h"
#include "ModuleProgramCodeBlock.h"
#include "ObjectAllocationProfileInlines.h"
@@ -1242,7 +1243,9 @@
for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
switch (Interpreter::getOpcodeID(curInstruction[0])) {
- case op_get_by_id: {
+ case op_get_by_id:
+ case op_get_by_id_proto_load:
+ case op_get_by_id_unset: {
StructureID oldStructureID = curInstruction[4].u.structureID;
if (!oldStructureID || Heap::isMarked(vm.heap.structureIDTable().get(oldStructureID)))
break;
@@ -1336,6 +1339,12 @@
}
}
+ // We can't just remove all the sets when we clear the caches since we might have created a watchpoint set
+ // then cleared the cache without GCing in between.
+ m_llintGetByIdWatchpointMap.removeIf([](const StructureWatchpointMap::KeyValuePairType& pair) -> bool {
+ return !Heap::isMarked(pair.key);
+ });
+
for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
if (Options::verboseOSR())
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/CodeBlock.h (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/CodeBlock.h 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/CodeBlock.h 2018-05-17 05:11:20 UTC (rev 231887)
@@ -54,6 +54,7 @@
#include "JSGlobalObject.h"
#include "JumpTable.h"
#include "LLIntCallLinkInfo.h"
+#include "LLIntPrototypeLoadAdaptiveStructureWatchpoint.h"
#include "LazyOperandValueProfile.h"
#include "ModuleProgramExecutable.h"
#include "ObjectAllocationProfile.h"
@@ -626,6 +627,9 @@
return m_llintExecuteCounter;
}
+ typedef HashMap<Structure*, Bag<LLIntPrototypeLoadAdaptiveStructureWatchpoint>> StructureWatchpointMap;
+ StructureWatchpointMap& llintGetByIdWatchpointMap() { return m_llintGetByIdWatchpointMap; }
+
// Functions for controlling when tiered compilation kicks in. This
// controls both when the optimizing compiler is invoked and when OSR
// entry happens. Two triggers exist: the loop trigger and the return
@@ -970,6 +974,7 @@
RefCountedArray<LLIntCallLinkInfo> m_llintCallLinkInfos;
SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo>> m_incomingLLIntCalls;
+ StructureWatchpointMap m_llintGetByIdWatchpointMap;
PoisonedRefPtr<CodeBlockPoison, JITCode> m_jitCode;
#if ENABLE(JIT)
std::unique_ptr<RegisterAtOffsetList> m_calleeSaveRegisters;
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/GetByIdStatus.cpp (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2018-05-17 05:11:20 UTC (rev 231887)
@@ -104,7 +104,11 @@
}
case op_get_array_length:
- case op_try_get_by_id: {
+ case op_try_get_by_id:
+ case op_get_by_id_proto_load:
+ case op_get_by_id_unset: {
+ // FIXME: We should not just bail if we see a try_get_by_id or a get_by_id_proto_load.
+ // https://bugs.webkit.org/show_bug.cgi?id=158039
return GetByIdStatus(NoInformation, false);
}
Added: branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp (0 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp (rev 0)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp 2018-05-17 05:11:20 UTC (rev 231887)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016-2017 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 "LLIntPrototypeLoadAdaptiveStructureWatchpoint.h"
+
+#include "CodeBlock.h"
+#include "Instruction.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint(const ObjectPropertyCondition& key, Instruction* getByIdInstruction)
+ : m_key(key)
+ , m_getByIdInstruction(getByIdInstruction)
+{
+ RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
+ RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
+}
+
+void LLIntPrototypeLoadAdaptiveStructureWatchpoint::install()
+{
+ RELEASE_ASSERT(m_key.isWatchable());
+
+ m_key.object()->structure()->addTransitionWatchpoint(this);
+}
+
+void LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal(const FireDetail&)
+{
+ if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
+ install();
+ return;
+ }
+
+ CodeBlock::clearLLIntGetByIdCache(m_getByIdInstruction);
+}
+
+} // namespace JSC
Added: branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h (0 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h (rev 0)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h 2018-05-17 05:11:20 UTC (rev 231887)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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 "Instruction.h"
+#include "ObjectPropertyCondition.h"
+#include "Watchpoint.h"
+
+namespace JSC {
+
+class LLIntPrototypeLoadAdaptiveStructureWatchpoint : public Watchpoint {
+public:
+ LLIntPrototypeLoadAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, Instruction*);
+
+ void install();
+
+protected:
+ void fireInternal(const FireDetail&) override;
+
+private:
+ ObjectPropertyCondition m_key;
+ Instruction* m_getByIdInstruction;
+};
+
+} // namespace JSC
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2018-05-17 05:11:20 UTC (rev 231887)
@@ -2701,6 +2701,7 @@
instructions().append(0);
instructions().append(0);
instructions().append(0);
+ instructions().append(Options::prototypeHitCountForLLIntCaching());
instructions().append(profile);
return dst;
}
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-05-17 05:11:20 UTC (rev 231887)
@@ -5153,6 +5153,8 @@
case op_get_by_id_direct:
case op_try_get_by_id:
case op_get_by_id:
+ case op_get_by_id_proto_load:
+ case op_get_by_id_unset:
case op_get_array_length: {
SpeculatedType prediction = getPrediction();
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/dfg/DFGCapabilities.cpp (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/dfg/DFGCapabilities.cpp 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/dfg/DFGCapabilities.cpp 2018-05-17 05:11:20 UTC (rev 231887)
@@ -164,6 +164,8 @@
case op_put_by_val_direct:
case op_try_get_by_id:
case op_get_by_id:
+ case op_get_by_id_proto_load:
+ case op_get_by_id_unset:
case op_get_by_id_with_this:
case op_get_by_id_direct:
case op_get_by_val_with_this:
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/jit/JIT.cpp (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/jit/JIT.cpp 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/jit/JIT.cpp 2018-05-17 05:11:20 UTC (rev 231887)
@@ -342,6 +342,8 @@
DEFINE_OP(op_beloweq)
DEFINE_OP(op_try_get_by_id)
case op_get_array_length:
+ case op_get_by_id_proto_load:
+ case op_get_by_id_unset:
DEFINE_OP(op_get_by_id)
DEFINE_OP(op_get_by_id_with_this)
DEFINE_OP(op_get_by_id_direct)
@@ -519,6 +521,8 @@
DEFINE_SLOWCASE_OP(op_eq)
DEFINE_SLOWCASE_OP(op_try_get_by_id)
case op_get_array_length:
+ case op_get_by_id_proto_load:
+ case op_get_by_id_unset:
DEFINE_SLOWCASE_OP(op_get_by_id)
DEFINE_SLOWCASE_OP(op_get_by_id_with_this)
DEFINE_SLOWCASE_OP(op_get_by_id_direct)
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2018-05-17 05:11:20 UTC (rev 231887)
@@ -641,6 +641,63 @@
LLINT_RETURN_PROFILED(op_get_by_id_direct, result);
}
+
+static void setupGetByIdPrototypeCache(ExecState* exec, VM& vm, Instruction* pc, JSCell* baseCell, PropertySlot& slot, const Identifier& ident)
+{
+ CodeBlock* codeBlock = exec->codeBlock();
+ Structure* structure = baseCell->structure();
+
+ if (structure->typeInfo().prohibitsPropertyCaching())
+ return;
+
+ if (structure->needImpurePropertyWatchpoint())
+ return;
+
+ if (structure->isDictionary()) {
+ if (structure->hasBeenFlattenedBefore())
+ return;
+ structure->flattenDictionaryStructure(vm, jsCast<JSObject*>(baseCell));
+ }
+
+ ObjectPropertyConditionSet conditions;
+ if (slot.isUnset())
+ conditions = generateConditionsForPropertyMiss(vm, codeBlock, exec, structure, ident.impl());
+ else
+ conditions = generateConditionsForPrototypePropertyHit(vm, codeBlock, exec, structure, slot.slotBase(), ident.impl());
+
+ if (!conditions.isValid())
+ return;
+
+ PropertyOffset offset = invalidOffset;
+ CodeBlock::StructureWatchpointMap& watchpointMap = codeBlock->llintGetByIdWatchpointMap();
+ auto result = watchpointMap.add(structure, Bag<LLIntPrototypeLoadAdaptiveStructureWatchpoint>());
+ for (ObjectPropertyCondition condition : conditions) {
+ if (!condition.isWatchable())
+ return;
+ if (condition.condition().kind() == PropertyCondition::Presence)
+ offset = condition.condition().offset();
+ result.iterator->value.add(condition, pc)->install();
+ }
+ ASSERT((offset == invalidOffset) == slot.isUnset());
+
+ ConcurrentJSLocker locker(codeBlock->m_lock);
+
+ if (slot.isUnset()) {
+ pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_unset);
+ pc[4].u.structureID = structure->id();
+ return;
+ }
+ ASSERT(slot.isValue());
+
+ pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_proto_load);
+ pc[4].u.structureID = structure->id();
+ pc[5].u.operand = offset;
+ // We know that this pointer will remain valid because it will be cleared by either a watchpoint fire or
+ // during GC when we clear the LLInt caches.
+ pc[6].u.pointer = slot.slotBase();
+}
+
+
LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
{
LLINT_BEGIN();
@@ -661,7 +718,9 @@
StructureID oldStructureID = pc[4].u.structureID;
if (oldStructureID) {
auto opcode = Interpreter::getOpcodeID(pc[0]);
- if (opcode == op_get_by_id) {
+ if (opcode == op_get_by_id
+ || opcode == op_get_by_id_unset
+ || opcode == op_get_by_id_proto_load) {
Structure* a = vm.heap.structureIDTable().get(oldStructureID);
Structure* b = baseValue.asCell()->structure(vm);
@@ -680,6 +739,9 @@
pc[0].u.opcode = LLInt::getOpcode(op_get_by_id);
pc[4].u.pointer = nullptr; // old structure
pc[5].u.pointer = nullptr; // offset
+
+ // Prevent the prototype cache from ever happening.
+ pc[7].u.operand = 0;
if (structure->propertyAccessesAreCacheable()
&& !structure->needImpurePropertyWatchpoint()) {
@@ -690,6 +752,11 @@
pc[4].u.structureID = structure->id();
pc[5].u.operand = slot.cachedOffset();
}
+ } else if (UNLIKELY(pc[7].u.operand && (slot.isValue() || slot.isUnset()))) {
+ ASSERT(slot.slotBase() != baseValue);
+
+ if (!(--pc[7].u.operand))
+ setupGetByIdPrototypeCache(exec, vm, pc, baseCell, slot, ident);
}
} else if (!LLINT_ALWAYS_ACCESS_SLOW
&& isJSArray(baseValue)
@@ -698,6 +765,9 @@
ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(codeBlock->bytecodeOffset(pc));
arrayProfile->observeStructure(baseValue.asCell()->structure());
pc[4].u.arrayProfile = arrayProfile;
+
+ // Prevent the prototype cache from ever happening.
+ pc[7].u.operand = 0;
}
pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2018-05-17 05:11:20 UTC (rev 231887)
@@ -1420,7 +1420,7 @@
loadi 4[PC], t2
storei t0, TagOffset[cfr, t2, 8]
storei t1, PayloadOffset[cfr, t2, 8]
- valueProfile(t0, t1, 28, t2)
+ valueProfile(t0, t1, 32, t2)
dispatch(constexpr op_get_by_id_length)
.opGetByIdSlow:
@@ -1428,6 +1428,43 @@
dispatch(constexpr op_get_by_id_length)
+_llint_op_get_by_id_proto_load:
+ traceExecution()
+ loadi 8[PC], t0
+ loadi 16[PC], t1
+ loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdProtoSlow)
+ loadi 20[PC], t2
+ bineq JSCell::m_structureID[t3], t1, .opGetByIdProtoSlow
+ loadpFromInstruction(6, t3)
+ 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(constexpr op_get_by_id_proto_load_length)
+
+.opGetByIdProtoSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(constexpr op_get_by_id_proto_load_length)
+
+
+_llint_op_get_by_id_unset:
+ traceExecution()
+ loadi 8[PC], t0
+ loadi 16[PC], t1
+ loadConstantOrVariablePayload(t0, CellTag, t3, .opGetByIdUnsetSlow)
+ bineq JSCell::m_structureID[t3], t1, .opGetByIdUnsetSlow
+ loadi 4[PC], t2
+ storei UndefinedTag, TagOffset[cfr, t2, 8]
+ storei 0, PayloadOffset[cfr, t2, 8]
+ valueProfile(UndefinedTag, 0, 32, t2)
+ dispatch(constexpr op_get_by_id_unset_length)
+
+.opGetByIdUnsetSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(constexpr op_get_by_id_unset_length)
+
+
_llint_op_get_array_length:
traceExecution()
loadi 8[PC], t0
@@ -1441,7 +1478,7 @@
loadp JSObject::m_butterfly[t3], t0
loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
bilt t0, 0, .opGetArrayLengthSlow
- valueProfile(Int32Tag, t0, 28, t2)
+ valueProfile(Int32Tag, t0, 32, t2)
storep t0, PayloadOffset[cfr, t1, 8]
storep Int32Tag, TagOffset[cfr, t1, 8]
dispatch(constexpr op_get_array_length_length)
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2018-05-17 05:11:20 UTC (rev 231887)
@@ -1342,7 +1342,7 @@
loadisFromInstruction(1, t2)
loadPropertyAtVariableOffset(t1, t3, t0)
storeq t0, [cfr, t2, 8]
- valueProfile(t0, constexpr (op_get_by_id_length - 1), t1)
+ valueProfile(t0, 8, t1)
dispatch(constexpr op_get_by_id_length)
.opGetByIdSlow:
@@ -1350,6 +1350,43 @@
dispatch(constexpr op_get_by_id_length)
+_llint_op_get_by_id_proto_load:
+ traceExecution()
+ loadisFromInstruction(2, t0)
+ loadConstantOrVariableCell(t0, t3, .opGetByIdProtoSlow)
+ loadi JSCell::m_structureID[t3], t1
+ loadisFromInstruction(4, t2)
+ bineq t2, t1, .opGetByIdProtoSlow
+ loadisFromInstruction(5, t1)
+ loadpFromInstruction(6, t3)
+ loadisFromInstruction(1, t2)
+ loadPropertyAtVariableOffset(t1, t3, t0)
+ storeq t0, [cfr, t2, 8]
+ valueProfile(t0, 8, t1)
+ dispatch(constexpr op_get_by_id_proto_load_length)
+
+.opGetByIdProtoSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(constexpr op_get_by_id_proto_load_length)
+
+
+_llint_op_get_by_id_unset:
+ traceExecution()
+ loadisFromInstruction(2, t0)
+ loadConstantOrVariableCell(t0, t3, .opGetByIdUnsetSlow)
+ loadi JSCell::m_structureID[t3], t1
+ loadisFromInstruction(4, t2)
+ bineq t2, t1, .opGetByIdUnsetSlow
+ loadisFromInstruction(1, t2)
+ storeq ValueUndefined, [cfr, t2, 8]
+ valueProfile(ValueUndefined, 8, t1)
+ dispatch(constexpr op_get_by_id_unset_length)
+
+.opGetByIdUnsetSlow:
+ callSlowPath(_llint_slow_path_get_by_id)
+ dispatch(constexpr op_get_by_id_unset_length)
+
+
_llint_op_get_array_length:
traceExecution()
loadisFromInstruction(2, t0)
@@ -1364,7 +1401,7 @@
loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
bilt t0, 0, .opGetArrayLengthSlow
orq tagTypeNumber, t0
- valueProfile(t0, constexpr (op_get_array_length_length - 1), t2)
+ valueProfile(t0, 8, t2)
storeq t0, [cfr, t1, 8]
dispatch(constexpr op_get_array_length_length)
Modified: branches/safari-606.1.17-branch/Source/_javascript_Core/runtime/Options.h (231886 => 231887)
--- branches/safari-606.1.17-branch/Source/_javascript_Core/runtime/Options.h 2018-05-17 04:27:28 UTC (rev 231886)
+++ branches/safari-606.1.17-branch/Source/_javascript_Core/runtime/Options.h 2018-05-17 05:11:20 UTC (rev 231887)
@@ -457,6 +457,8 @@
\
v(bool, useICStats, false, Normal, nullptr) \
\
+ v(unsigned, prototypeHitCountForLLIntCaching, 2, Normal, "Number of prototype property hits before caching a prototype in the LLInt. A count of 0 means never cache.") \
+ \
v(bool, dumpCompiledRegExpPatterns, false, Normal, nullptr) \
\
v(bool, dumpModuleRecord, false, Normal, nullptr) \