WebKit Bugzilla
Attachment 340419 Details for
Bug 185652
: JSC should have InstanceOf inline caching
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
a bit more
blah.patch (text/plain), 30.45 KB, created by
Filip Pizlo
on 2018-05-15 10:31:50 PDT
(
hide
)
Description:
a bit more
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2018-05-15 10:31:50 PDT
Size:
30.45 KB
patch
obsolete
>Index: Source/JavaScriptCore/Sources.txt >=================================================================== >--- Source/JavaScriptCore/Sources.txt (revision 231772) >+++ Source/JavaScriptCore/Sources.txt (working copy) >@@ -222,6 +222,7 @@ bytecode/GetterSetterAccessCase.cpp > bytecode/InlineAccess.cpp > bytecode/InlineCallFrame.cpp > bytecode/InlineCallFrameSet.cpp >+bytecode/InstanceOfAccessCase.cpp > bytecode/IntrinsicGetterAccessCase.cpp > bytecode/JumpTable.cpp > bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 231772) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -310,6 +310,8 @@ > 0F485322187750560083B687 /* DFGArithMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485320187750560083B687 /* DFGArithMode.h */; }; > 0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485324187DFDEC0083B687 /* FTLAvailableRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F49E9A920AB4CFE001CA0AA /* InstanceOfAccessCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F49E9A720AB4CFB001CA0AA /* InstanceOfAccessCase.cpp */; }; >+ 0F49E9AA20AB4D00001CA0AA /* InstanceOfAccessCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F49E9A820AB4CFB001CA0AA /* InstanceOfAccessCase.h */; }; > 0F4A38FA1C8E13DF00190318 /* SuperSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4A38F81C8E13DF00190318 /* SuperSampler.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F4AE0431FE0D25700E20839 /* InferredValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4AE0421FE0D25400E20839 /* InferredValueInlines.h */; }; > 0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -2299,6 +2301,8 @@ > 0F485325187DFDEC0083B687 /* FTLRecoveryOpcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLRecoveryOpcode.cpp; path = ftl/FTLRecoveryOpcode.cpp; sourceTree = "<group>"; }; > 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLRecoveryOpcode.h; path = ftl/FTLRecoveryOpcode.h; sourceTree = "<group>"; }; > 0F493AF816D0CAD10084508B /* SourceProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProvider.cpp; sourceTree = "<group>"; }; >+ 0F49E9A720AB4CFB001CA0AA /* InstanceOfAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InstanceOfAccessCase.cpp; sourceTree = "<group>"; }; >+ 0F49E9A820AB4CFB001CA0AA /* InstanceOfAccessCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InstanceOfAccessCase.h; sourceTree = "<group>"; }; > 0F4A38F71C8E13DF00190318 /* SuperSampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SuperSampler.cpp; sourceTree = "<group>"; }; > 0F4A38F81C8E13DF00190318 /* SuperSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuperSampler.h; sourceTree = "<group>"; }; > 0F4AE0421FE0D25400E20839 /* InferredValueInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InferredValueInlines.h; sourceTree = "<group>"; }; >@@ -5962,6 +5966,8 @@ > 534E034D1E4D4B1600213F64 /* AccessCase.h */, > 53B0BE331E561AC900A8FC29 /* GetterSetterAccessCase.cpp */, > 534E03571E53BF2F00213F64 /* GetterSetterAccessCase.h */, >+ 0F49E9A720AB4CFB001CA0AA /* InstanceOfAccessCase.cpp */, >+ 0F49E9A820AB4CFB001CA0AA /* InstanceOfAccessCase.h */, > 53B0BE371E561B2400A8FC29 /* IntrinsicGetterAccessCase.cpp */, > 534E03531E53BD2900213F64 /* IntrinsicGetterAccessCase.h */, > 53B0BE351E561B0900A8FC29 /* ProxyableAccessCase.cpp */, >@@ -9208,6 +9214,7 @@ > 7C008CE7187631B600955C24 /* Microtask.h in Headers */, > FE2A87601F02381600EB31B2 /* MinimumReservedZoneSize.h in Headers */, > 86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */, >+ 0F49E9AA20AB4D00001CA0AA /* InstanceOfAccessCase.h in Headers */, > C4703CD7192844CC0013FBEA /* models.py in Headers */, > E3794E761B77EB97005543AE /* ModuleAnalyzer.h in Headers */, > 9F63434577274FAFB9336C38 /* ModuleNamespaceAccessCase.h in Headers */, >@@ -10303,6 +10310,7 @@ > 530A66C21FA3E78B0026A545 /* UnifiedSource143.cpp in Sources */, > 530A66C31FA3E78B0026A545 /* UnifiedSource144.cpp in Sources */, > 530A66C41FA3E78B0026A545 /* UnifiedSource145.cpp in Sources */, >+ 0F49E9A920AB4CFE001CA0AA /* InstanceOfAccessCase.cpp in Sources */, > ); > runOnlyForDeploymentPostprocessing = 0; > }; >Index: Source/JavaScriptCore/bytecode/AccessCase.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/AccessCase.cpp (revision 231772) >+++ Source/JavaScriptCore/bytecode/AccessCase.cpp (working copy) >@@ -221,12 +221,13 @@ bool AccessCase::canReplace(const Access > { > // This puts in a good effort to try to figure out if 'other' is made superfluous by '*this'. > // It's fine for this to return false if it's in doubt. >- >+ > switch (type()) { > case ArrayLength: > case StringLength: > case DirectArgumentsLength: > case ScopedArgumentsLength: >+ case InstanceOfGeneric: > return other.type() == type(); > case ModuleNamespaceLoad: { > if (other.type() != type()) >@@ -235,6 +236,16 @@ bool AccessCase::canReplace(const Access > auto& otherCase = this->as<ModuleNamespaceAccessCase>(); > return thisCase.moduleNamespaceObject() == otherCase.moduleNamespaceObject(); > } >+ case InstanceOfHit: >+ case InstanceOfMiss: { >+ if (other.type() != type()) >+ return false; >+ >+ if (this->as<InstanceOfAccessCase>().prototype() != other.as<InstanceOfAccessCase>().prototype()) >+ return false; >+ >+ return structure() == other.structure(); >+ } > default: > if (other.type() != type()) > return false; >@@ -311,6 +322,9 @@ bool AccessCase::visitWeak(VM& vm) const > return false; > if (accessCase.moduleEnvironment() && !Heap::isMarked(accessCase.moduleEnvironment())) > return false; >+ } else if (type() == InstanceOfHit || type() == InstanceOfMiss) { >+ if (as<InstanceOfAccessCase>().prototype() && !Heap::isMarked(as<InstanceOfAccessCase>().prototype())) >+ return false; > } > > return true; >@@ -565,6 +579,19 @@ void AccessCase::generateImpl(AccessGene > state.succeed(); > return; > >+ case InstanceOfHit: >+ case InstanceOfMiss: >+ state.failAndRepatch.append( >+ jit.branch(CCallHelpers::NotEqual, thisGPR, CCallHelpers::TrustedImmPtr(as<InstanceOfAccessCase>().prototype()))); >+ >+ jit.boxBooleanPayload(m_type == InstanceOfHit, valueRegs.payloadGPR()); >+ state.succeed(); >+ return; >+ >+ case InstanceOfGeneric: >+ // FIXME >+ return; >+ > case Miss: > jit.moveTrustedValue(jsUndefined(), valueRegs); > state.succeed(); >Index: Source/JavaScriptCore/bytecode/AccessCase.h >=================================================================== >--- Source/JavaScriptCore/bytecode/AccessCase.h (revision 231772) >+++ Source/JavaScriptCore/bytecode/AccessCase.h (working copy) >@@ -99,6 +99,9 @@ public: > DirectArgumentsLength, > ScopedArgumentsLength, > ModuleNamespaceLoad, >+ InstanceOfHit, >+ InstanceOfMiss, >+ InstanceOfGeneric > }; > > enum State : uint8_t { >@@ -126,7 +129,7 @@ public: > // This create method should be used for transitions. > static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, PropertyOffset, Structure* oldStructure, > Structure* newStructure, const ObjectPropertyConditionSet&, std::unique_ptr<PolyProtoAccessChain>); >- >+ > static std::unique_ptr<AccessCase> fromStructureStubInfo(VM&, JSCell* owner, StructureStubInfo&); > > AccessType type() const { return m_type; } >Index: Source/JavaScriptCore/bytecode/InstanceOfAccessCase.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/InstanceOfAccessCase.cpp (nonexistent) >+++ Source/JavaScriptCore/bytecode/InstanceOfAccessCase.cpp (working copy) >@@ -0,0 +1,68 @@ >+/* >+ * 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. >+ */ >+ >+#include "config.h" >+#include "InstanceOfAccessCase.h" >+ >+#if ENABLE(JIT) >+ >+namespace JSC { >+ >+std::unique_ptr<AccessCase> InstanceOfAccessCase::create( >+ VM& vm, JSCell* owner, AccessType accessType, Structure* structure, >+ const ObjectPropertyConditionSet& conditionSet, JSObject* prototype) >+{ >+ return std::unique_ptr<AccessCase>(new InstanceOfAccessCase(vm, owner, accessType, structure, conditionSet, prototype)); >+} >+ >+void InstanceOfAccessCase::dumpImpl(PrintStream& out, CommaPrinter& comma) const >+{ >+ Base::dumpImpl(out, comma); >+ out.print(comma, "prototype = ", JSValue(prototype())); >+} >+ >+std::unique_ptr<AccessCase> InstanceOfAccessCase::clone() const >+{ >+ std::unique_ptr<ProxyableAccessCase> result(new InstanceOfAccessCase(*this)); >+ result->resetState(); >+ return WTFMove(result); >+} >+ >+InstanceOfAccessCase::~InstanceOfAccessCase() >+{ >+} >+ >+InstanceOfAccessCase::InstanceOfAccessCase( >+ VM& vm, JSCell* owner, AccessType accessType, Structure* structure, >+ const ObjectPropertyConditionSet& conditionSet, JSObject* prototype) >+ : Base(vm, owner, accessType, invalidOffset, structure, conditionSet) >+ , m_prototype(vm, owner, prototype) >+{ >+} >+ >+} // namespace JSC >+ >+#endif // ENABLE(JIT) >+ >Index: Source/JavaScriptCore/bytecode/InstanceOfAccessCase.h >=================================================================== >--- Source/JavaScriptCore/bytecode/InstanceOfAccessCase.h (nonexistent) >+++ Source/JavaScriptCore/bytecode/InstanceOfAccessCase.h (working copy) >@@ -0,0 +1,61 @@ >+/* >+ * 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 >+ >+#if ENABLE(JIT) >+ >+#include "AccessCase.h" >+ >+namespace JSC { >+ >+class InstanceOfAccessCase : public AccessCase { >+public: >+ using Base = AccessCase; >+ >+ static std::unique_ptr<AccessCase> create( >+ VM&, JSCell*, AccessType, Structure*, const ObjectPropertyConditionSet&, >+ JSObject* prototype); >+ >+ JSObject* prototype() const { return m_prototype.get(); } >+ >+ void dumpImpl(PrintStream&, CommaPrinter&) const override; >+ std::unique_ptr<AccessCase> clone() const override; >+ >+ ~InstanceOfAccessCase(); >+ >+protected: >+ InstanceOfAccessCase( >+ VM&, JSCell*, AccessType, Structure*, const ObjectPropertyConditionSet&, >+ JSObject* prototype); >+ >+private: >+ WriteBarrier<JSObject> m_prototype; >+}; >+ >+} // namespace JSC >+ >+#endif // ENABLE(JIT) >+ >Index: Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (revision 231772) >+++ Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (working copy) >@@ -248,7 +248,7 @@ AccessGenerationResult PolymorphicAccess > > casesToAdd.append(WTFMove(myCase)); > } >- >+ > if (PolymorphicAccessInternal::verbose) > dataLog("casesToAdd: ", listDump(casesToAdd), "\n"); > >@@ -258,39 +258,41 @@ AccessGenerationResult PolymorphicAccess > if (casesToAdd.isEmpty()) > return AccessGenerationResult::MadeNoChanges; > >- bool shouldReset = false; >- AccessGenerationResult resetResult(AccessGenerationResult::ResetStubAndFireWatchpoints); >- auto considerPolyProtoReset = [&] (Structure* a, Structure* b) { >- if (Structure::shouldConvertToPolyProto(a, b)) { >- // For now, we only reset if this is our first time invalidating this watchpoint. >- // The reason we don't immediately fire this watchpoint is that we may be already >- // watching the poly proto watchpoint, which if fired, would destroy us. We let >- // the person handling the result to do a delayed fire. >- ASSERT(a->rareData()->sharedPolyProtoWatchpoint().get() == b->rareData()->sharedPolyProtoWatchpoint().get()); >- if (a->rareData()->sharedPolyProtoWatchpoint()->isStillValid()) { >- shouldReset = true; >- resetResult.addWatchpointToFire(*a->rareData()->sharedPolyProtoWatchpoint(), StringFireDetail("Detected poly proto optimization opportunity.")); >+ if (stubInfo.accessType != AccessType::InstanceOf) { >+ bool shouldReset = false; >+ AccessGenerationResult resetResult(AccessGenerationResult::ResetStubAndFireWatchpoints); >+ auto considerPolyProtoReset = [&] (Structure* a, Structure* b) { >+ if (Structure::shouldConvertToPolyProto(a, b)) { >+ // For now, we only reset if this is our first time invalidating this watchpoint. >+ // The reason we don't immediately fire this watchpoint is that we may be already >+ // watching the poly proto watchpoint, which if fired, would destroy us. We let >+ // the person handling the result to do a delayed fire. >+ ASSERT(a->rareData()->sharedPolyProtoWatchpoint().get() == b->rareData()->sharedPolyProtoWatchpoint().get()); >+ if (a->rareData()->sharedPolyProtoWatchpoint()->isStillValid()) { >+ shouldReset = true; >+ resetResult.addWatchpointToFire(*a->rareData()->sharedPolyProtoWatchpoint(), StringFireDetail("Detected poly proto optimization opportunity.")); >+ } > } >- } >- }; >+ }; > >- for (auto& caseToAdd : casesToAdd) { >- for (auto& existingCase : m_list) { >- Structure* a = caseToAdd->structure(); >- Structure* b = existingCase->structure(); >- considerPolyProtoReset(a, b); >+ for (auto& caseToAdd : casesToAdd) { >+ for (auto& existingCase : m_list) { >+ Structure* a = caseToAdd->structure(); >+ Structure* b = existingCase->structure(); >+ considerPolyProtoReset(a, b); >+ } > } >- } >- for (unsigned i = 0; i < casesToAdd.size(); ++i) { >- for (unsigned j = i + 1; j < casesToAdd.size(); ++j) { >- Structure* a = casesToAdd[i]->structure(); >- Structure* b = casesToAdd[j]->structure(); >- considerPolyProtoReset(a, b); >+ for (unsigned i = 0; i < casesToAdd.size(); ++i) { >+ for (unsigned j = i + 1; j < casesToAdd.size(); ++j) { >+ Structure* a = casesToAdd[i]->structure(); >+ Structure* b = casesToAdd[j]->structure(); >+ considerPolyProtoReset(a, b); >+ } > } >- } > >- if (shouldReset) >- return resetResult; >+ if (shouldReset) >+ return resetResult; >+ } > > // Now add things to the new list. Note that at this point, we will still have old cases that > // may be replaced by the new ones. That's fine. We will sort that out when we regenerate. >@@ -438,6 +440,18 @@ AccessGenerationResult PolymorphicAccess > } > m_list.resize(dstIndex); > >+ bool generatedFinalCode = false; >+ >+ // If the resulting set of cases is so big that we would stop caching and this is InstanceOf, >+ // then we want to generate the generic InstanceOf and then stop. >+ if (m_list.size() >= Options::maxAccessVariantListSize() >+ && stubInfo.accessType == AccessType::InstanceOf) { >+ while (!cases.isEmpty()) >+ m_list.append(cases.takeLast()); >+ cases.append(AccessCAse::create(vm, codeBlock, InstanceOfGeneric)); >+ generatedFinalCode = true; >+ } >+ > if (PolymorphicAccessInternal::verbose) > dataLog("Optimized cases: ", listDump(cases), "\n"); > >@@ -586,7 +600,7 @@ AccessGenerationResult PolymorphicAccess > m_list = WTFMove(cases); > > AccessGenerationResult::Kind resultKind; >- if (m_list.size() >= Options::maxAccessVariantListSize()) >+ if (m_list.size() >= Options::maxAccessVariantListSize() || generatedFinalCode) > resultKind = AccessGenerationResult::GeneratedFinalCode; > else > resultKind = AccessGenerationResult::GeneratedNewCode; >Index: Source/JavaScriptCore/bytecode/StructureStubInfo.h >=================================================================== >--- Source/JavaScriptCore/bytecode/StructureStubInfo.h (revision 231772) >+++ Source/JavaScriptCore/bytecode/StructureStubInfo.h (working copy) >@@ -50,7 +50,8 @@ enum class AccessType : int8_t { > GetDirect, > TryGet, > Put, >- In >+ In, >+ InstanceOf > }; > > enum class CacheType : int8_t { >@@ -138,6 +139,10 @@ public: > // we don't already have a case buffered for. Note that if this returns true but the > // bufferingCountdown is not zero then we will buffer the access case for later without > // immediately generating code for it. >+ // >+ // NOTE: This will behave oddly for InstanceOf if the user varies the prototype but not >+ // the base's structure. That seems unlikely for the canonical use of instanceof, where >+ // the prototype is fixed. > bool isNewlyAdded = bufferedStructures.add(structure); > if (isNewlyAdded) { > VM& vm = *codeBlock->vm(); >@@ -169,7 +174,7 @@ public: > StructureSet bufferedStructures; > > struct { >- CodeLocationLabel<JITStubRoutinePtrTag> start; // This is either the start of the inline IC for *byId caches, or the location of patchable jump for 'in' caches. >+ CodeLocationLabel<JITStubRoutinePtrTag> start; // This is either the start of the inline IC for *byId caches, or the location of patchable jump for 'in' and 'instanceof' caches. > RegisterSet usedRegisters; > uint32_t inlineSize; > int32_t deltaFromStartToSlowPathCallLocation; >Index: Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp >=================================================================== >--- Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp (revision 231772) >+++ Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp (working copy) >@@ -43,23 +43,44 @@ static StructureStubInfo* garbageStubInf > } > > JITInlineCacheGenerator::JITInlineCacheGenerator( >- CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, AccessType accessType) >+ CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, AccessType accessType, >+ const RegisterSet& usedRegisters) > : m_codeBlock(codeBlock) > { > m_stubInfo = m_codeBlock ? m_codeBlock->addStubInfo(accessType) : garbageStubInfo(); > m_stubInfo->codeOrigin = codeOrigin; > m_stubInfo->callSiteIndex = callSite; >+ >+ m_stubInfo->patch.usedRegisters = usedRegisters; >+} >+ >+JITInlineCacheGenerator::~JITInlineCacheGenerator() >+{ >+} >+ >+void JITInlineCacheGenerator::finalize( >+ LinkBuffer& fastPath, LinkBuffer& slowPath, CodeLocationLabel<JITStubRoutinePtrTag> start) >+{ >+ m_stubInfo->patch.start = start; >+ >+ int32_t inlineSize = MacroAssembler::differenceBetweenCodePtr( >+ start, fastPath.locationOf<NoPtrTag>(m_done)); >+ ASSERT(inlineSize > 0); >+ m_stubInfo->patch.inlineSize = inlineSize; >+ >+ m_stubInfo->patch.deltaFromStartToSlowPathCallLocation = MacroAssembler::differenceBetweenCodePtr( >+ start, slowPath.locationOf<NoPtrTag>(m_slowPathCall)); >+ m_stubInfo->patch.deltaFromStartToSlowPathStart = MacroAssembler::differenceBetweenCodePtr( >+ start, slowPath.locationOf<NoPtrTag>(m_slowPathBegin)); > } > > JITByIdGenerator::JITByIdGenerator( > CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, AccessType accessType, > const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs value) >- : JITInlineCacheGenerator(codeBlock, codeOrigin, callSite, accessType) >+ : JITInlineCacheGenerator(codeBlock, codeOrigin, callSite, accessType, usedRegisters) > , m_base(base) > , m_value(value) > { >- m_stubInfo->patch.usedRegisters = usedRegisters; >- > m_stubInfo->patch.baseGPR = static_cast<int8_t>(base.payloadGPR()); > m_stubInfo->patch.valueGPR = static_cast<int8_t>(value.payloadGPR()); > m_stubInfo->patch.thisGPR = static_cast<int8_t>(InvalidGPRReg); >@@ -73,23 +94,8 @@ JITByIdGenerator::JITByIdGenerator( > void JITByIdGenerator::finalize(LinkBuffer& fastPath, LinkBuffer& slowPath) > { > ASSERT(m_start.isSet()); >- CodeLocationLabel<JITStubRoutinePtrTag> start = fastPath.locationOf<JITStubRoutinePtrTag>(m_start); >- m_stubInfo->patch.start = start; >- >- int32_t inlineSize = MacroAssembler::differenceBetweenCodePtr( >- start, fastPath.locationOf<NoPtrTag>(m_done)); >- ASSERT(inlineSize > 0); >- m_stubInfo->patch.inlineSize = inlineSize; >- >- m_stubInfo->patch.deltaFromStartToSlowPathCallLocation = MacroAssembler::differenceBetweenCodePtr( >- start, slowPath.locationOf<NoPtrTag>(m_slowPathCall)); >- m_stubInfo->patch.deltaFromStartToSlowPathStart = MacroAssembler::differenceBetweenCodePtr( >- start, slowPath.locationOf<NoPtrTag>(m_slowPathBegin)); >-} >- >-void JITByIdGenerator::finalize(LinkBuffer& linkBuffer) >-{ >- finalize(linkBuffer, linkBuffer); >+ JITInlineCacheGenerator::finalize( >+ fastPath, slowPath, fastPath.locationOf<JITStubRoutinePtrTag>(m_start)); > } > > void JITByIdGenerator::generateFastCommon(MacroAssembler& jit, size_t inlineICSize) >@@ -165,6 +171,37 @@ V_JITOperation_ESsiJJI JITPutByIdGenerat > return operationPutByIdNonStrictOptimize; > } > >+void JITInstanceOfGenerator::JITInstanceOfGenerator( >+ CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, >+ const RegisterSet& usedRegisters, GPRReg result, GPRReg value, GPRReg prototype, >+ GPRReg scratch1, GPRReg scratch2) >+ : JITInlineCacheGenerator( >+ codeBlock, codeOrigin, callSiteIndex, AccessType::InstanceOf, usedRegisters) >+ , m_result(result) >+ , m_value(value) >+ , m_prototype(prototype) >+{ >+ m_stubInfo->patch.baseGPR = static_cast<int8_t>(value); >+ m_stubInfo->patch.valueGPR = static_cast<int8_t>(result); >+ m_stubInfo->patch.thisGPR = static_cast<int8_t>(prototype); >+ >+ m_stubInfo->patch.usedRegisters.clear(result); >+ m_stubInfo->patch.usedRegisters.clear(scratch1); >+ m_stubInfo->patch.usedRegisters.clear(scratch2); >+} >+ >+void JITInstanceOfGenerator::generateFastPath(MacroAssembler& jit) >+{ >+ m_jump = m_jit.patchableJump(); >+} >+ >+void JITInstanceOfGenerator::finalize(LinkBuffer& fastPath, LinkBuffer& slowPath) >+{ >+ JITInlineCacheGenerator::finalize( >+ fastPath, slowPath, >+ linkBuffer.locationOf<JITStubRoutinePtrTag>(m_jump)); >+} >+ > } // namespace JSC > > #endif // ENABLE(JIT) >Index: Source/JavaScriptCore/jit/JITInlineCacheGenerator.h >=================================================================== >--- Source/JavaScriptCore/jit/JITInlineCacheGenerator.h (revision 231772) >+++ Source/JavaScriptCore/jit/JITInlineCacheGenerator.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved. >+ * Copyright (C) 2013-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 >@@ -45,14 +45,31 @@ enum class AccessType : int8_t; > class JITInlineCacheGenerator { > protected: > JITInlineCacheGenerator() { } >- JITInlineCacheGenerator(CodeBlock*, CodeOrigin, CallSiteIndex, AccessType); >+ JITInlineCacheGenerator( >+ CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters); > > public: > StructureStubInfo* stubInfo() const { return m_stubInfo; } > >+ void reportSlowPathCall(MacroAssembler::Label slowPathBegin, MacroAssembler::Call call) >+ { >+ m_slowPathBegin = slowPathBegin; >+ m_slowPathCall = call; >+ } >+ >+ MacroAssembler::Label slowPathBegin() const { return m_slowPathBegin; } >+ >+ void finalize( >+ LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer, >+ CodeLocationLabel<JITStubRoutinePtrTag> start); >+ > protected: > CodeBlock* m_codeBlock; > StructureStubInfo* m_stubInfo; >+ >+ MacroAssembler::Label m_done; >+ MacroAssembler::Label m_slowPathBegin; >+ MacroAssembler::Call m_slowPathCall; > }; > > class JITByIdGenerator : public JITInlineCacheGenerator { >@@ -60,36 +77,27 @@ protected: > JITByIdGenerator() { } > > JITByIdGenerator( >- CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet&, JSValueRegs base, >- JSValueRegs value); >- >+ CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters, >+ JSValueRegs base, JSValueRegs value); >+ > public: >- void reportSlowPathCall(MacroAssembler::Label slowPathBegin, MacroAssembler::Call call) >- { >- m_slowPathBegin = slowPathBegin; >- m_slowPathCall = call; >- } >- >- MacroAssembler::Label slowPathBegin() const { return m_slowPathBegin; } > MacroAssembler::Jump slowPathJump() const > { > ASSERT(m_slowPathJump.isSet()); > return m_slowPathJump; > } > >- void finalize(LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer); >- void finalize(LinkBuffer&); >+ void finalize( >+ LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer); > > protected: >+ > void generateFastCommon(MacroAssembler&, size_t size); > > JSValueRegs m_base; > JSValueRegs m_value; >- >+ > MacroAssembler::Label m_start; >- MacroAssembler::Label m_done; >- MacroAssembler::Label m_slowPathBegin; >- MacroAssembler::Call m_slowPathCall; > MacroAssembler::Jump m_slowPathJump; > }; > >@@ -124,7 +132,7 @@ public: > > JITPutByIdGenerator( > CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base, >- JSValueRegs, GPRReg scratch, ECMAMode, PutKind); >+ JSValueRegs value, GPRReg scratch, ECMAMode, PutKind); > > void generateFastPath(MacroAssembler&); > >@@ -135,6 +143,26 @@ private: > PutKind m_putKind; > }; > >+class JITInstanceOfGenerator : public JITInlineCacheGenerator { >+public: >+ JITInstanceOfGenerator() { } >+ >+ JITInstanceOfGenerator( >+ CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, GPRReg result, >+ GPRReg value, GPRReg prototype, GPRReg scratch1, GPRReg scratch2); >+ >+ void generateFastPath(MacroAssembler&); >+ >+ void finalize(LinkBuffer& fastPathLinkBuffer, LinkBuffer& slowPathLinkBuffer); >+ >+private: >+ GPRReg m_result; >+ GPRReg m_value; >+ GPRReg m_prototype; >+ >+ MacroAssembler::PatchableJump m_jump; >+}; >+ > } // namespace JSC > > #endif // ENABLE(JIT) >Index: Source/JavaScriptCore/runtime/Options.h >=================================================================== >--- Source/JavaScriptCore/runtime/Options.h (revision 231772) >+++ Source/JavaScriptCore/runtime/Options.h (working copy) >@@ -284,7 +284,7 @@ constexpr bool enableWebAssemblyStreamin > v(bool, logExecutableAllocation, false, Normal, nullptr) \ > \ > v(bool, useConcurrentJIT, true, Normal, "allows the DFG / FTL compilation in threads other than the executing JS thread") \ >- v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(3, 2) - 1, Normal, nullptr) \ >+ v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(MAXIMUM_NUMBER_OF_FTL_COMPILER_THREADS, 2) - 1, Normal, nullptr) \ > v(unsigned, numberOfFTLCompilerThreads, computeNumberOfWorkerThreads(MAXIMUM_NUMBER_OF_FTL_COMPILER_THREADS, 2) - 1, Normal, nullptr) \ > v(int32, priorityDeltaOfDFGCompilerThreads, computePriorityDeltaOfWorkerThreads(-1, 0), Normal, nullptr) \ > v(int32, priorityDeltaOfFTLCompilerThreads, computePriorityDeltaOfWorkerThreads(-2, 0), Normal, nullptr) \
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 185652
:
340417
|
340419
|
340440
|
340446
|
340499
|
340511
|
340512
|
340537
|
340548
|
340549
|
340551
|
340555
|
340556
|
340573
|
340574
|
340576
|
340580
|
340585
|
340593
|
340616
|
340636
|
340649
|
340665
|
340703
|
340704