Ignore:
Timestamp:
Feb 26, 2017, 4:32:10 PM (8 years ago)
Author:
[email protected]
Message:

op_get_by_id_with_this should use inline caching
https://bugs.webkit.org/show_bug.cgi?id=162124

Patch by Caio Lima <Caio Lima> on 2017-02-26
Reviewed by Saam Barati.

JSTests:

  • microbenchmarks/super-getter.js: Added.

(A.prototype.get f):
(A):
(B.prototype.get f):
(B):

  • stress/super-force-ic-fail.js: Added.

(let.assert):
(let.aObj.get foo):
(let.obj.jaz):
(let.bObj.get foo):
(let.obj2.foo):

  • stress/super-get-by-id.js: Added.

(assert):
(Base):
(Base.prototype.get name):
(Base.prototype.set name):
(Subclass.prototype.get name):
(Subclass):
(getterName):
(getterValue):
(PolymorphicSubclass.prototype.get value):
(PolymorphicSubclass):
(i.let.BaseCode):
(i.get value):
(MegamorphicSubclass.prototype.get value):
(MegamorphicSubclass):
(let.subObj.get value):
(i.catch):
(subObj.get value):
(BaseException):
(BaseException.prototype.get name):
(SubclassException.prototype.get name):
(SubclassException):
(prototype.foo):
(prototype.get name):
(SubclassExceptionComplex.prototype.get name):
(SubclassExceptionComplex):

  • stress/super-getter-reset-ic.js: Added.

(let.assert):
(let.B.f):

Source/JavaScriptCore:

This patch is enabling inline cache for op_get_by_id_with_this in all
tiers. It means that operations using super.member are going to
be able to be optimized by PIC. To enable it, we introduced a new
member of StructureStubInfo.patch named thisGPR, created a new class
to manage the IC named JITGetByIdWithThisGenerator and changed
PolymorphicAccess.regenerate that uses StructureStubInfo.patch.thisGPR
to decide the correct this value on inline caches.
With inline cached enabled, super.member are ~4.5x faster,
according microbenchmarks.

  • bytecode/AccessCase.cpp:

(JSC::AccessCase::generateImpl):

  • bytecode/PolymorphicAccess.cpp:

(JSC::PolymorphicAccess::regenerate):

  • bytecode/PolymorphicAccess.h:
  • bytecode/StructureStubInfo.cpp:

(JSC::StructureStubInfo::reset):

  • bytecode/StructureStubInfo.h:
  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::addGetByIdWithThis):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileIn):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::cachedGetByIdWithThis):
(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileGetByIdWithThis):
(JSC::FTL::DFG::LowerDFGToB3::compileIn):
(JSC::FTL::DFG::LowerDFGToB3::getByIdWithThis):

  • jit/CCallHelpers.h:

(JSC::CCallHelpers::setupArgumentsWithExecState):

  • jit/ICStats.h:
  • jit/JIT.cpp:

(JSC::JIT::JIT):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::link):

  • jit/JIT.h:
  • jit/JITInlineCacheGenerator.cpp:

(JSC::JITByIdGenerator::JITByIdGenerator):
(JSC::JITGetByIdWithThisGenerator::JITGetByIdWithThisGenerator):
(JSC::JITGetByIdWithThisGenerator::generateFastPath):

  • jit/JITInlineCacheGenerator.h:

(JSC::JITGetByIdWithThisGenerator::JITGetByIdWithThisGenerator):

  • jit/JITInlines.h:

(JSC::JIT::callOperation):

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emit_op_get_by_id_with_this):
(JSC::JIT::emitSlow_op_get_by_id_with_this):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_get_by_id_with_this):
(JSC::JIT::emitSlow_op_get_by_id_with_this):

  • jit/Repatch.cpp:

(JSC::appropriateOptimizingGetByIdFunction):
(JSC::appropriateGenericGetByIdFunction):
(JSC::tryCacheGetByID):

  • jit/Repatch.h:
  • jsc.cpp:

(WTF::CustomGetter::getOwnPropertySlot):
(WTF::CustomGetter::customGetterAcessor):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jsc.cpp

    r212778 r213019  
    370370            return true;
    371371        }
     372       
     373        if (propertyName == PropertyName(Identifier::fromString(exec, "customGetterAccessor"))) {
     374            slot.setCacheableCustom(thisObject, DontDelete | ReadOnly | DontEnum | CustomAccessor, thisObject->customGetterAcessor);
     375            return true;
     376        }
     377       
    372378        return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
    373379    }
     
    380386
    381387        CustomGetter* thisObject = jsDynamicCast<CustomGetter*>(vm, JSValue::decode(thisValue));
     388        if (!thisObject)
     389            return throwVMTypeError(exec, scope);
     390        bool shouldThrow = thisObject->get(exec, PropertyName(Identifier::fromString(exec, "shouldThrow"))).toBoolean(exec);
     391        if (shouldThrow)
     392            return throwVMTypeError(exec, scope);
     393        return JSValue::encode(jsNumber(100));
     394    }
     395   
     396    static EncodedJSValue customGetterAcessor(ExecState* exec, EncodedJSValue thisValue, PropertyName)
     397    {
     398        VM& vm = exec->vm();
     399        auto scope = DECLARE_THROW_SCOPE(vm);
     400       
     401        JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
    382402        if (!thisObject)
    383403            return throwVMTypeError(exec, scope);
Note: See TracChangeset for help on using the changeset viewer.