Changeset 199170 in webkit
- Timestamp:
- Apr 7, 2016, 12:38:00 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 40 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r199166 r199170 1 2016-04-07 Keith Miller <keith_miller@apple.com> 2 3 We should support the ability to do a non-effectful getById 4 https://bugs.webkit.org/show_bug.cgi?id=156116 5 6 Reviewed by Benjamin Poulain. 7 8 Currently, there is no way in JS to do a non-effectful getById. A non-effectful getById is 9 useful because it enables us to take different code paths based on values that we would 10 otherwise not be able to have knowledge of. This patch adds this new feature called 11 try_get_by_id that will attempt to do as much of a get_by_id as possible without performing 12 an effectful behavior. Thus, try_get_by_id will return the value if the slot is a value, the 13 GetterSetter object if the slot is a normal accessor (not a CustomGetterSetter) and 14 undefined if the slot is unset. If the slot is proxied or any other cases then the result 15 is null. In theory, if we ever wanted to check for null we could add a sentinal object to 16 the global object that indicates we could not get the result. 17 18 In order to implement this feature we add a new enum GetByIdKind that indicates what to do 19 for accessor properties in PolymorphicAccess. If the GetByIdKind is pure then we treat the 20 get_by_id the same way we would for load and return the value at the appropriate offset. 21 Additionally, in order to make sure the we can properly compare the GetterSetter object 22 with === GetterSetters are now JSObjects. This comes at the cost of eight extra bytes on the 23 GetterSetter object but it vastly simplifies the patch. Additionally, the extra bytes are 24 likely to have little to no impact on memory usage as normal accessors are generally rare. 25 26 * JavaScriptCore.xcodeproj/project.pbxproj: 27 * builtins/BuiltinExecutableCreator.cpp: Added. 28 (JSC::createBuiltinExecutable): 29 * builtins/BuiltinExecutableCreator.h: Copied from Source/JavaScriptCore/builtins/BuiltinExecutables.h. 30 * builtins/BuiltinExecutables.cpp: 31 (JSC::BuiltinExecutables::createDefaultConstructor): 32 (JSC::BuiltinExecutables::createBuiltinExecutable): 33 (JSC::createBuiltinExecutable): 34 (JSC::BuiltinExecutables::createExecutable): 35 (JSC::createExecutableInternal): Deleted. 36 * builtins/BuiltinExecutables.h: 37 * bytecode/BytecodeIntrinsicRegistry.h: 38 * bytecode/BytecodeList.json: 39 * bytecode/BytecodeUseDef.h: 40 (JSC::computeUsesForBytecodeOffset): 41 (JSC::computeDefsForBytecodeOffset): 42 * bytecode/CodeBlock.cpp: 43 (JSC::CodeBlock::dumpBytecode): 44 * bytecode/PolymorphicAccess.cpp: 45 (JSC::AccessCase::tryGet): 46 (JSC::AccessCase::generate): 47 (WTF::printInternal): 48 * bytecode/PolymorphicAccess.h: 49 (JSC::AccessCase::isGet): Deleted. 50 (JSC::AccessCase::isPut): Deleted. 51 (JSC::AccessCase::isIn): Deleted. 52 * bytecode/StructureStubInfo.cpp: 53 (JSC::StructureStubInfo::reset): 54 * bytecode/StructureStubInfo.h: 55 * bytecompiler/BytecodeGenerator.cpp: 56 (JSC::BytecodeGenerator::emitTryGetById): 57 * bytecompiler/BytecodeGenerator.h: 58 * bytecompiler/NodesCodegen.cpp: 59 (JSC::BytecodeIntrinsicNode::emit_intrinsic_tryGetById): 60 * dfg/DFGSpeculativeJIT32_64.cpp: 61 (JSC::DFG::SpeculativeJIT::cachedGetById): 62 * dfg/DFGSpeculativeJIT64.cpp: 63 (JSC::DFG::SpeculativeJIT::cachedGetById): 64 * ftl/FTLLowerDFGToB3.cpp: 65 (JSC::FTL::DFG::LowerDFGToB3::getById): 66 * jit/JIT.cpp: 67 (JSC::JIT::privateCompileMainPass): 68 (JSC::JIT::privateCompileSlowCases): 69 * jit/JIT.h: 70 * jit/JITInlineCacheGenerator.cpp: 71 (JSC::JITGetByIdGenerator::JITGetByIdGenerator): 72 * jit/JITInlineCacheGenerator.h: 73 * jit/JITInlines.h: 74 (JSC::JIT::callOperation): 75 * jit/JITOperations.cpp: 76 * jit/JITOperations.h: 77 * jit/JITPropertyAccess.cpp: 78 (JSC::JIT::emitGetByValWithCachedId): 79 (JSC::JIT::emit_op_try_get_by_id): 80 (JSC::JIT::emitSlow_op_try_get_by_id): 81 (JSC::JIT::emit_op_get_by_id): 82 * jit/JITPropertyAccess32_64.cpp: 83 (JSC::JIT::emitGetByValWithCachedId): 84 (JSC::JIT::emit_op_try_get_by_id): 85 (JSC::JIT::emitSlow_op_try_get_by_id): 86 (JSC::JIT::emit_op_get_by_id): 87 * jit/Repatch.cpp: 88 (JSC::repatchByIdSelfAccess): 89 (JSC::appropriateOptimizingGetByIdFunction): 90 (JSC::appropriateGenericGetByIdFunction): 91 (JSC::tryCacheGetByID): 92 (JSC::repatchGetByID): 93 (JSC::resetGetByID): 94 * jit/Repatch.h: 95 * jsc.cpp: 96 (GlobalObject::finishCreation): 97 (functionGetGetterSetter): 98 (functionCreateBuiltin): 99 * llint/LLIntData.cpp: 100 (JSC::LLInt::Data::performAssertions): 101 * llint/LLIntSlowPaths.cpp: 102 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 103 * llint/LLIntSlowPaths.h: 104 * llint/LowLevelInterpreter.asm: 105 * runtime/GetterSetter.cpp: 106 * runtime/GetterSetter.h: 107 * runtime/JSType.h: 108 * runtime/PropertySlot.cpp: 109 (JSC::PropertySlot::getPureResult): 110 * runtime/PropertySlot.h: 111 * runtime/ProxyObject.cpp: 112 (JSC::ProxyObject::getOwnPropertySlotCommon): 113 * tests/stress/try-get-by-id.js: Added. 114 (tryGetByIdText): 115 (getCaller.obj.1.throw.new.Error.let.func): 116 (getCaller.obj.1.throw.new.Error): 117 (throw.new.Error.get let): 118 (throw.new.Error.): 119 (throw.new.Error.let.get createBuiltin): 120 (get let): 121 (let.get createBuiltin): 122 (let.func): 123 (get let.func): 124 (get throw): 125 1 126 2016-04-07 Filip Pizlo <fpizlo@apple.com> 2 127 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r199164 r199170 1996 1996 DC17E8191C9C91DB008A6AB3 /* ShadowChickenInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */; }; 1997 1997 DC17E81A1C9C91E9008A6AB3 /* CCallHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */; }; 1998 DE26E9031CB5DD0500D2BE82 /* BuiltinExecutableCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = DE26E9021CB5DD0500D2BE82 /* BuiltinExecutableCreator.h */; }; 1999 DE26E9071CB5DEFB00D2BE82 /* BuiltinExecutableCreator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE26E9061CB5DD9600D2BE82 /* BuiltinExecutableCreator.cpp */; }; 1998 2000 DE5A0A001BA3AC3E003D4424 /* IntrinsicEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */; }; 1999 2001 DEA7E2441BBC677200D78440 /* JSTypedArrayViewPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */; }; … … 4205 4207 DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowChickenInlines.h; sourceTree = "<group>"; }; 4206 4208 DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCallHelpers.cpp; sourceTree = "<group>"; }; 4209 DE26E9021CB5DD0500D2BE82 /* BuiltinExecutableCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltinExecutableCreator.h; sourceTree = "<group>"; }; 4210 DE26E9061CB5DD9600D2BE82 /* BuiltinExecutableCreator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BuiltinExecutableCreator.cpp; sourceTree = "<group>"; }; 4207 4211 DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicEmitter.cpp; sourceTree = "<group>"; }; 4208 4212 E124A8F50E555775003091F1 /* OpaqueJSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueJSString.h; sourceTree = "<group>"; }; … … 6839 6843 7CF9BC581B65D9A3009DB1EF /* ArrayConstructor.js */, 6840 6844 7CF9BC591B65D9A3009DB1EF /* ArrayIteratorPrototype.js */, 6845 DE26E9061CB5DD9600D2BE82 /* BuiltinExecutableCreator.cpp */, 6846 DE26E9021CB5DD0500D2BE82 /* BuiltinExecutableCreator.h */, 6841 6847 A7D801A11880D66E0026C39B /* BuiltinExecutables.cpp */, 6842 6848 A7D801A21880D66E0026C39B /* BuiltinExecutables.h */, … … 7384 7390 0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */, 7385 7391 0F3AC754188E5EC80032029F /* ExitingJITType.h in Headers */, 7392 DE26E9031CB5DD0500D2BE82 /* BuiltinExecutableCreator.h in Headers */, 7386 7393 0FB105861675481200F8AB6E /* ExitKind.h in Headers */, 7387 7394 0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */, … … 8778 8785 0F38B01717CFE75500B144D3 /* DFGCompilationKey.cpp in Sources */, 8779 8786 0F38B01917CFE75500B144D3 /* DFGCompilationMode.cpp in Sources */, 8787 DE26E9071CB5DEFB00D2BE82 /* BuiltinExecutableCreator.cpp in Sources */, 8780 8788 0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */, 8781 8789 0FED67B91B26256D0066CE15 /* DFGConstantHoistingPhase.cpp in Sources */, -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutableCreator.cpp
r199169 r199170 1 1 /* 2 * Copyright (C) 201 4Apple Inc. All rights reserved.2 * Copyright (C) 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #i fndef BuiltinExecutables_h27 # define BuiltinExecutables_h26 #include "config.h" 27 #include "BuiltinExecutableCreator.h" 28 28 29 #include "JSCBuiltins.h" 30 #include "ParserModes.h" 31 #include "SourceCode.h" 32 #include "Weak.h" 33 #include "WeakHandleOwner.h" 29 #include "BuiltinExecutables.h" 34 30 35 31 namespace JSC { 36 32 37 class UnlinkedFunctionExecutable; 38 class Identifier; 39 class VM; 40 41 class BuiltinExecutables final: private WeakHandleOwner { 42 WTF_MAKE_FAST_ALLOCATED; 43 public: 44 explicit BuiltinExecutables(VM&); 45 46 #define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, length) \ 47 UnlinkedFunctionExecutable* name##Executable(); \ 48 const SourceCode& name##Source() { return m_##name##Source; } 33 UnlinkedFunctionExecutable* createBuiltinExecutable(VM& vm, const SourceCode& source, const Identifier& ident, ConstructorKind kind, ConstructAbility ability) 34 { 35 return BuiltinExecutables::createExecutable(vm, source, ident, kind, ability); 36 } 49 37 50 JSC_FOREACH_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES) 51 #undef EXPOSE_BUILTIN_SOURCES 52 53 UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name); 54 55 private: 56 void finalize(Handle<Unknown>, void* context) override; 57 58 VM& m_vm; 59 60 UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode&, const Identifier&, ConstructAbility); 61 62 #define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, length)\ 63 SourceCode m_##name##Source; \ 64 Weak<UnlinkedFunctionExecutable> m_##name##Executable; 65 JSC_FOREACH_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS) 66 #undef DECLARE_BUILTIN_SOURCE_MEMBERS 67 }; 68 69 } 70 71 #endif 38 } // namespace JSC -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutableCreator.h
r199169 r199170 1 1 /* 2 * Copyright (C) 201 4Apple Inc. All rights reserved.2 * Copyright (C) 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #ifndef BuiltinExecutable s_h27 #define BuiltinExecutable s_h26 #ifndef BuiltinExecutableCreator_h 27 #define BuiltinExecutableCreator_h 28 28 29 #include " JSCBuiltins.h"29 #include "ConstructAbility.h" 30 30 #include "ParserModes.h" 31 31 #include "SourceCode.h" 32 #include "Weak.h"33 #include "WeakHandleOwner.h"34 32 35 33 namespace JSC { 36 34 37 class UnlinkedFunctionExecutable; 38 class Identifier; 39 class VM; 35 JS_EXPORT_PRIVATE UnlinkedFunctionExecutable* createBuiltinExecutable(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility); 40 36 41 class BuiltinExecutables final: private WeakHandleOwner { 42 WTF_MAKE_FAST_ALLOCATED; 43 public: 44 explicit BuiltinExecutables(VM&); 37 } // namespace JSC 45 38 46 #define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, length) \ 47 UnlinkedFunctionExecutable* name##Executable(); \ 48 const SourceCode& name##Source() { return m_##name##Source; } 49 50 JSC_FOREACH_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES) 51 #undef EXPOSE_BUILTIN_SOURCES 52 53 UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name); 54 55 private: 56 void finalize(Handle<Unknown>, void* context) override; 57 58 VM& m_vm; 59 60 UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode&, const Identifier&, ConstructAbility); 61 62 #define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, length)\ 63 SourceCode m_##name##Source; \ 64 Weak<UnlinkedFunctionExecutable> m_##name##Executable; 65 JSC_FOREACH_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS) 66 #undef DECLARE_BUILTIN_SOURCE_MEMBERS 67 }; 68 69 } 70 71 #endif 39 #endif /* BuiltinExecutableCreator_h */ -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
r199108 r199170 36 36 namespace JSC { 37 37 38 static UnlinkedFunctionExecutable* createExecutableInternal(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility);39 40 38 BuiltinExecutables::BuiltinExecutables(VM& vm) 41 39 : m_vm(vm) … … 55 53 break; 56 54 case ConstructorKind::Base: 57 return createExecutable Internal(m_vm, makeSource(baseConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);55 return createExecutable(m_vm, makeSource(baseConstructorCode), name, constructorKind, ConstructAbility::CanConstruct); 58 56 case ConstructorKind::Derived: 59 return createExecutable Internal(m_vm, makeSource(derivedConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);57 return createExecutable(m_vm, makeSource(derivedConstructorCode), name, constructorKind, ConstructAbility::CanConstruct); 60 58 } 61 59 ASSERT_NOT_REACHED(); … … 65 63 UnlinkedFunctionExecutable* BuiltinExecutables::createBuiltinExecutable(const SourceCode& code, const Identifier& name, ConstructAbility constructAbility) 66 64 { 67 return createExecutable Internal(m_vm, code, name, ConstructorKind::None, constructAbility);65 return createExecutable(m_vm, code, name, ConstructorKind::None, constructAbility); 68 66 } 69 67 70 68 UnlinkedFunctionExecutable* createBuiltinExecutable(VM& vm, const SourceCode& code, const Identifier& name, ConstructAbility constructAbility) 71 69 { 72 return createExecutableInternal(vm, code, name, ConstructorKind::None, constructAbility);70 return BuiltinExecutables::createExecutable(vm, code, name, ConstructorKind::None, constructAbility); 73 71 } 74 72 75 UnlinkedFunctionExecutable* createExecutableInternal(VM& vm, const SourceCode& source, const Identifier& name, ConstructorKind constructorKind, ConstructAbility constructAbility)73 UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const SourceCode& source, const Identifier& name, ConstructorKind constructorKind, ConstructAbility constructAbility) 76 74 { 77 75 JSTextPosition positionBeforeLastNewline; -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.h
r199108 r199170 53 53 UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name); 54 54 55 static UnlinkedFunctionExecutable* createExecutable(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility); 55 56 private: 56 57 void finalize(Handle<Unknown>, void* context) override; -
trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
r199164 r199170 42 42 macro(assert) \ 43 43 macro(isObject) \ 44 macro(tryGetById) \ 44 45 macro(putByValDirect) \ 45 46 macro(toString) -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.json
r199108 r199170 58 58 { "name" : "op_is_function", "length" : 3 }, 59 59 { "name" : "op_in", "length" : 4 }, 60 { "name" : "op_try_get_by_id", "length" : 4 }, 60 61 { "name" : "op_get_by_id", "length" : 9 }, 61 62 { "name" : "op_get_array_length", "length" : 9 }, -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r199108 r199170 144 144 case op_get_from_scope: 145 145 case op_to_primitive: 146 case op_try_get_by_id: 146 147 case op_get_by_id: 147 148 case op_get_array_length: … … 368 369 case op_call_eval: 369 370 case op_construct: 371 case op_try_get_by_id: 370 372 case op_get_by_id: 371 373 case op_get_array_length: -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r199108 r199170 1094 1094 case op_in: { 1095 1095 printBinaryOp(out, exec, location, it, "in"); 1096 break; 1097 } 1098 case op_try_get_by_id: { 1099 int r0 = (++it)->u.operand; 1100 int r1 = (++it)->u.operand; 1101 int id0 = (++it)->u.operand; 1102 printLocationAndOp(out, exec, location, it, "try_get_by_id"); 1103 out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data()); 1096 1104 break; 1097 1105 } -
trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
r199166 r199170 160 160 } 161 161 162 std::unique_ptr<AccessCase> AccessCase::tryGet( 163 VM& vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure, 164 const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet) 165 { 166 std::unique_ptr<AccessCase> result(new AccessCase()); 167 168 result->m_type = type; 169 result->m_offset = offset; 170 result->m_structure.set(vm, owner, structure); 171 result->m_conditionSet = conditionSet; 172 173 if (viaProxy || additionalSet) { 174 result->m_rareData = std::make_unique<RareData>(); 175 result->m_rareData->viaProxy = viaProxy; 176 result->m_rareData->additionalSet = additionalSet; 177 } 178 179 return result; 180 } 181 162 182 std::unique_ptr<AccessCase> AccessCase::get( 163 183 VM& vm, JSCell* owner, AccessType type, PropertyOffset offset, Structure* structure, … … 686 706 687 707 case Load: 708 case GetGetter: 688 709 case Getter: 689 710 case Setter: … … 721 742 GPRReg loadedValueGPR = InvalidGPRReg; 722 743 if (m_type != CustomValueGetter && m_type != CustomAccessorGetter && m_type != CustomValueSetter && m_type != CustomAccessorSetter) { 723 if (m_type == Load )744 if (m_type == Load || m_type == GetGetter) 724 745 loadedValueGPR = valueRegs.payloadGPR(); 725 746 else … … 740 761 CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset)), loadedValueGPR); 741 762 #else 742 if (m_type == Load ) {763 if (m_type == Load || m_type == GetGetter) { 743 764 jit.load32( 744 765 CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + TagOffset), … … 751 772 } 752 773 753 if (m_type == Load ) {774 if (m_type == Load || m_type == GetGetter) { 754 775 state.succeed(); 755 776 return; … … 1568 1589 out.print("Miss"); 1569 1590 return; 1591 case AccessCase::GetGetter: 1592 out.print("GetGetter"); 1593 return; 1570 1594 case AccessCase::Getter: 1571 1595 out.print("Getter"); -
trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h
r199108 r199170 58 58 Replace, 59 59 Miss, 60 GetGetter, 60 61 Getter, 61 62 Setter, … … 71 72 }; 72 73 73 static bool isGet(AccessType type) 74 { 75 switch (type) { 76 case Transition: 77 case Replace: 78 case Setter: 79 case CustomValueSetter: 80 case CustomAccessorSetter: 81 case InHit: 82 case InMiss: 83 return false; 84 case Load: 85 case MegamorphicLoad: 86 case Miss: 87 case Getter: 88 case CustomValueGetter: 89 case CustomAccessorGetter: 90 case IntrinsicGetter: 91 case ArrayLength: 92 case StringLength: 93 return true; 94 } 95 } 96 97 static bool isPut(AccessType type) 98 { 99 switch (type) { 100 case Load: 101 case MegamorphicLoad: 102 case Miss: 103 case Getter: 104 case CustomValueGetter: 105 case CustomAccessorGetter: 106 case IntrinsicGetter: 107 case InHit: 108 case InMiss: 109 case ArrayLength: 110 case StringLength: 111 return false; 112 case Transition: 113 case Replace: 114 case Setter: 115 case CustomValueSetter: 116 case CustomAccessorSetter: 117 return true; 118 } 119 } 120 121 static bool isIn(AccessType type) 122 { 123 switch (type) { 124 case Load: 125 case MegamorphicLoad: 126 case Miss: 127 case Getter: 128 case CustomValueGetter: 129 case CustomAccessorGetter: 130 case IntrinsicGetter: 131 case Transition: 132 case Replace: 133 case Setter: 134 case CustomValueSetter: 135 case CustomAccessorSetter: 136 case ArrayLength: 137 case StringLength: 138 return false; 139 case InHit: 140 case InMiss: 141 return true; 142 } 143 } 74 static std::unique_ptr<AccessCase> tryGet( 75 VM&, JSCell* owner, AccessType, PropertyOffset, Structure*, 76 const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(), 77 bool viaProxy = false, 78 WatchpointSet* additionalSet = nullptr); 144 79 145 80 static std::unique_ptr<AccessCase> get( -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
r199162 r199170 149 149 150 150 switch (accessType) { 151 case AccessType::GetPure: 152 resetGetByID(codeBlock, *this, GetByIDKind::Pure); 153 break; 151 154 case AccessType::Get: 152 resetGetByID(codeBlock, *this );155 resetGetByID(codeBlock, *this, GetByIDKind::Normal); 153 156 break; 154 157 case AccessType::Put: -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h
r199108 r199170 48 48 enum class AccessType : int8_t { 49 49 Get, 50 GetPure, 50 51 Put, 51 52 In -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r199108 r199170 2358 2358 instructions().append(constructor->index()); 2359 2359 instructions().append(hasInstanceValue->index()); 2360 return dst; 2361 } 2362 2363 RegisterID* BytecodeGenerator::emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property) 2364 { 2365 ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties are not supported with tryGetById."); 2366 2367 emitOpcode(op_try_get_by_id); 2368 instructions().append(kill(dst)); 2369 instructions().append(base->index()); 2370 instructions().append(addConstant(property)); 2360 2371 return dst; 2361 2372 } -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r199108 r199170 541 541 RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); } 542 542 543 RegisterID* emitTryGetById(RegisterID* dst, RegisterID* base, const Identifier& property); 543 544 RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property); 544 545 RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value); -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r199108 r199170 841 841 842 842 return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get())); 843 } 844 845 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_tryGetById(BytecodeGenerator& generator, RegisterID* dst) 846 { 847 ArgumentListNode* node = m_args->m_listNode; 848 RefPtr<RegisterID> base = generator.emitNode(node); 849 node = node->m_next; 850 851 // Since this is a builtin we expect the creator to use a string literal as the second argument. 852 ASSERT(node->m_expr->isString()); 853 const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value(); 854 ASSERT(!node->m_next); 855 856 RegisterID* finalDest = generator.finalDestination(dst); 857 return generator.emitTryGetById(finalDest, base.get(), ident); 843 858 } 844 859 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r199164 r199170 195 195 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, 196 196 JSValueRegs(baseTagGPROrNone, basePayloadGPR), 197 JSValueRegs(resultTagGPR, resultPayloadGPR) );197 JSValueRegs(resultTagGPR, resultPayloadGPR), AccessType::Get); 198 198 199 199 gen.generateFastPath(m_jit); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r199164 r199170 165 165 JITGetByIdGenerator gen( 166 166 m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, JSValueRegs(baseGPR), 167 JSValueRegs(resultGPR) );167 JSValueRegs(resultGPR), AccessType::Get); 168 168 gen.generateFastPath(m_jit); 169 169 -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r199164 r199170 7332 7332 jit.codeBlock(), node->origin.semantic, callSiteIndex, 7333 7333 params.unavailableRegisters(), JSValueRegs(params[1].gpr()), 7334 JSValueRegs(params[0].gpr()) );7334 JSValueRegs(params[0].gpr()), AccessType::Get); 7335 7335 7336 7336 generator->generateFastPath(jit); -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r199108 r199170 229 229 DEFINE_OP(op_eq) 230 230 DEFINE_OP(op_eq_null) 231 DEFINE_OP(op_try_get_by_id) 231 232 case op_get_array_length: 232 233 DEFINE_OP(op_get_by_id) … … 407 408 DEFINE_SLOWCASE_OP(op_div) 408 409 DEFINE_SLOWCASE_OP(op_eq) 410 DEFINE_SLOWCASE_OP(op_try_get_by_id) 409 411 case op_get_array_length: 410 412 DEFINE_SLOWCASE_OP(op_get_by_id) -
trunk/Source/JavaScriptCore/jit/JIT.h
r199108 r199170 503 503 void emit_op_eq(Instruction*); 504 504 void emit_op_eq_null(Instruction*); 505 void emit_op_try_get_by_id(Instruction*); 505 506 void emit_op_get_by_id(Instruction*); 506 507 void emit_op_get_arguments_length(Instruction*); … … 615 616 void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&); 616 617 void emitSlow_op_get_callee(Instruction*, Vector<SlowCaseEntry>::iterator&); 618 void emitSlow_op_try_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); 617 619 void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&); 618 620 void emitSlow_op_get_arguments_length(Instruction*, Vector<SlowCaseEntry>::iterator&); … … 739 741 MacroAssembler::Call callOperation(J_JITOperation_EJ, int, GPRReg); 740 742 #if USE(JSVALUE64) 743 MacroAssembler::Call callOperation(J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, UniquedStringImpl*); 741 744 MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, UniquedStringImpl*); 742 745 #else 746 MacroAssembler::Call callOperation(J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, GPRReg, UniquedStringImpl*); 743 747 MacroAssembler::Call callOperation(WithProfileTag, J_JITOperation_ESsiJI, int, StructureStubInfo*, GPRReg, GPRReg, UniquedStringImpl*); 744 748 #endif -
trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp
r199108 r199170 105 105 JITGetByIdGenerator::JITGetByIdGenerator( 106 106 CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSite, const RegisterSet& usedRegisters, 107 JSValueRegs base, JSValueRegs value )107 JSValueRegs base, JSValueRegs value, AccessType accessType) 108 108 : JITByIdGenerator( 109 codeBlock, codeOrigin, callSite, AccessType::Get, usedRegisters, base, value)109 codeBlock, codeOrigin, callSite, accessType, usedRegisters, base, value) 110 110 { 111 111 RELEASE_ASSERT(base.payloadGPR() != value.tagGPR()); -
trunk/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h
r199108 r199170 97 97 JITGetByIdGenerator( 98 98 CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base, 99 JSValueRegs value );99 JSValueRegs value, AccessType); 100 100 101 101 void generateFastPath(MacroAssembler&); -
trunk/Source/JavaScriptCore/jit/JITInlines.h
r199108 r199170 460 460 } 461 461 462 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid) 463 { 464 setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid)); 465 return appendCallWithExceptionCheckSetJSValueResult(operation, dst); 466 } 467 462 468 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid) 463 469 { … … 640 646 { 641 647 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag); 648 return appendCallWithExceptionCheckSetJSValueResult(operation, dst); 649 } 650 651 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid) 652 { 653 setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid)); 642 654 return appendCallWithExceptionCheckSetJSValueResult(operation, dst); 643 655 } -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r199140 r199170 157 157 } 158 158 159 EncodedJSValue JIT_OPERATION operationTryGetById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid) 160 { 161 VM* vm = &exec->vm(); 162 NativeCallFrameTracer tracer(vm, exec); 163 Identifier ident = Identifier::fromUid(vm, uid); 164 stubInfo->tookSlowPath = true; 165 166 JSValue baseValue = JSValue::decode(base); 167 PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry); 168 baseValue.getPropertySlot(exec, ident, slot); 169 170 return JSValue::encode(slot.getPureResult()); 171 } 172 173 EncodedJSValue JIT_OPERATION operationTryGetByIdOptimize(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid) 174 { 175 VM* vm = &exec->vm(); 176 NativeCallFrameTracer tracer(vm, exec); 177 Identifier ident = Identifier::fromUid(vm, uid); 178 179 JSValue baseValue = JSValue::decode(base); 180 PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry); 181 182 baseValue.getPropertySlot(exec, ident, slot); 183 if (stubInfo->considerCaching() && !slot.isTaintedByProxy() && (slot.isCacheableValue() || slot.isCacheableGetter() || slot.isUnset())) 184 repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Pure); 185 186 return JSValue::encode(slot.getPureResult()); 187 } 188 159 189 EncodedJSValue JIT_OPERATION operationGetById(ExecState* exec, StructureStubInfo* stubInfo, EncodedJSValue base, UniquedStringImpl* uid) 160 190 { … … 196 226 bool hasResult = baseValue.getPropertySlot(exec, ident, slot); 197 227 if (stubInfo->considerCaching()) 198 repatchGetByID(exec, baseValue, ident, slot, *stubInfo );228 repatchGetByID(exec, baseValue, ident, slot, *stubInfo, GetByIDKind::Normal); 199 229 200 230 return JSValue::encode(hasResult? slot.getValue(exec, ident) : jsUndefined()); -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r199164 r199170 288 288 int32_t JIT_OPERATION operationCallArityCheck(ExecState*) WTF_INTERNAL; 289 289 int32_t JIT_OPERATION operationConstructArityCheck(ExecState*) WTF_INTERNAL; 290 EncodedJSValue JIT_OPERATION operationTryGetById(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL; 291 EncodedJSValue JIT_OPERATION operationTryGetByIdOptimize(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL; 290 292 EncodedJSValue JIT_OPERATION operationGetById(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL; 291 293 EncodedJSValue JIT_OPERATION operationGetByIdGeneric(ExecState*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL; 292 EncodedJSValue JIT_OPERATION operationGetByIdBuildList(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;293 294 EncodedJSValue JIT_OPERATION operationGetByIdOptimize(ExecState*, StructureStubInfo*, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL; 294 295 EncodedJSValue JIT_OPERATION operationInOptimize(ExecState*, StructureStubInfo*, JSCell*, UniquedStringImpl*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r199108 r199170 214 214 JITGetByIdGenerator gen( 215 215 m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(), 216 JSValueRegs(regT0), JSValueRegs(regT0) );216 JSValueRegs(regT0), JSValueRegs(regT0), AccessType::Get); 217 217 gen.generateFastPath(*this); 218 218 … … 532 532 } 533 533 534 void JIT::emit_op_get_by_id(Instruction* currentInstruction) 534 void JIT::emit_op_try_get_by_id(Instruction* currentInstruction) 535 { 536 int resultVReg = currentInstruction[1].u.operand; 537 int baseVReg = currentInstruction[2].u.operand; 538 539 emitGetVirtualRegister(baseVReg, regT0); 540 541 emitJumpSlowCaseIfNotJSCell(regT0, baseVReg); 542 543 JITGetByIdGenerator gen( 544 m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(), 545 JSValueRegs(regT0), JSValueRegs(regT0), AccessType::GetPure); 546 gen.generateFastPath(*this); 547 addSlowCase(gen.slowPathJump()); 548 m_getByIds.append(gen); 549 550 emitPutVirtualRegister(resultVReg); 551 } 552 553 void JIT::emitSlow_op_try_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 535 554 { 536 555 int resultVReg = currentInstruction[1].u.operand; … … 538 557 const Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand)); 539 558 559 linkSlowCaseIfNotJSCell(iter, baseVReg); 560 linkSlowCase(iter); 561 562 JITGetByIdGenerator& gen = m_getByIds[m_getByIdIndex++]; 563 564 Label coldPathBegin = label(); 565 566 Call call = callOperation(operationTryGetByIdOptimize, resultVReg, gen.stubInfo(), regT0, ident->impl()); 567 568 gen.reportSlowPathCall(coldPathBegin, call); 569 } 570 571 void JIT::emit_op_get_by_id(Instruction* currentInstruction) 572 { 573 int resultVReg = currentInstruction[1].u.operand; 574 int baseVReg = currentInstruction[2].u.operand; 575 const Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand)); 576 540 577 emitGetVirtualRegister(baseVReg, regT0); 541 578 … … 547 584 JITGetByIdGenerator gen( 548 585 m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(m_bytecodeOffset), RegisterSet::stubUnavailableRegisters(), 549 JSValueRegs(regT0), JSValueRegs(regT0) );586 JSValueRegs(regT0), JSValueRegs(regT0), AccessType::Get); 550 587 gen.generateFastPath(*this); 551 588 addSlowCase(gen.slowPathJump()); -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r199108 r199170 283 283 JITGetByIdGenerator gen( 284 284 m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(), 285 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0) );285 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), AccessType::Get); 286 286 gen.generateFastPath(*this); 287 287 … … 574 574 } 575 575 576 void JIT::emit_op_try_get_by_id(Instruction* currentInstruction) 577 { 578 int dst = currentInstruction[1].u.operand; 579 int base = currentInstruction[2].u.operand; 580 581 emitLoad(base, regT1, regT0); 582 emitJumpSlowCaseIfNotJSCell(base, regT1); 583 584 JITGetByIdGenerator gen( 585 m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(), 586 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), AccessType::GetPure); 587 gen.generateFastPath(*this); 588 addSlowCase(gen.slowPathJump()); 589 m_getByIds.append(gen); 590 591 emitStore(dst, regT1, regT0); 592 } 593 594 void JIT::emitSlow_op_try_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 595 { 596 int resultVReg = currentInstruction[1].u.operand; 597 int baseVReg = currentInstruction[2].u.operand; 598 const Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand)); 599 600 linkSlowCaseIfNotJSCell(iter, baseVReg); 601 linkSlowCase(iter); 602 603 JITGetByIdGenerator& gen = m_getByIds[m_getByIdIndex++]; 604 605 Label coldPathBegin = label(); 606 607 Call call = callOperation(operationTryGetByIdOptimize, resultVReg, gen.stubInfo(), regT1, regT0, ident->impl()); 608 609 gen.reportSlowPathCall(coldPathBegin, call); 610 } 611 612 576 613 void JIT::emit_op_get_by_id(Instruction* currentInstruction) 577 614 { … … 588 625 JITGetByIdGenerator gen( 589 626 m_codeBlock, CodeOrigin(m_bytecodeOffset), CallSiteIndex(currentInstruction), RegisterSet::stubUnavailableRegisters(), 590 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0) );627 JSValueRegs::payloadOnly(regT0), JSValueRegs(regT1, regT0), AccessType::Get); 591 628 gen.generateFastPath(*this); 592 629 addSlowCase(gen.slowPathJump()); -
trunk/Source/JavaScriptCore/jit/Repatch.cpp
r199108 r199170 94 94 static void repatchByIdSelfAccess( 95 95 CodeBlock* codeBlock, StructureStubInfo& stubInfo, Structure* structure, 96 PropertyOffset offset, const FunctionPtr &slowPathFunction,96 PropertyOffset offset, const FunctionPtr& slowPathFunction, 97 97 bool compact) 98 98 { … … 214 214 } 215 215 216 static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo) 216 inline J_JITOperation_ESsiJI appropriateOptimizingGetByIdFunction(GetByIDKind kind) 217 { 218 if (kind == GetByIDKind::Normal) 219 return operationGetByIdOptimize; 220 return operationTryGetByIdOptimize; 221 } 222 223 inline J_JITOperation_ESsiJI appropriateGenericGetByIdFunction(GetByIDKind kind) 224 { 225 if (kind == GetByIDKind::Normal) 226 return operationGetById; 227 return operationTryGetById; 228 } 229 230 static InlineCacheAction tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByIDKind kind) 217 231 { 218 232 if (forceICFailure(exec)) … … 263 277 && !loadTargetFromProxy) { 264 278 structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset()); 265 repatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), operationGetByIdOptimize, true);279 repatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), appropriateOptimizingGetByIdFunction(kind), true); 266 280 stubInfo.initGetByIdSelf(codeBlock, structure, slot.cachedOffset()); 267 281 return RetryCacheLater; … … 296 310 getter = jsDynamicCast<JSFunction*>(slot.getterSetter()->getter()); 297 311 298 if (!loadTargetFromProxy && getter && AccessCase::canEmitIntrinsicGetter(getter, structure)) 312 if (kind == GetByIDKind::Pure) { 313 AccessCase::AccessType type; 314 if (slot.isCacheableValue()) 315 type = AccessCase::Load; 316 else if (slot.isUnset()) 317 type = AccessCase::Miss; 318 else if (slot.isCacheableGetter()) 319 type = AccessCase::GetGetter; 320 else 321 RELEASE_ASSERT_NOT_REACHED(); 322 323 newCase = AccessCase::tryGet(vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy, slot.watchpointSet()); 324 } else if (!loadTargetFromProxy && getter && AccessCase::canEmitIntrinsicGetter(getter, structure)) 299 325 newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet); 300 326 else { … … 331 357 } 332 358 333 void repatchGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo )359 void repatchGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByIDKind kind) 334 360 { 335 361 GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap); 336 362 337 if (tryCacheGetByID(exec, baseValue, propertyName, slot, stubInfo ) == GiveUpOnCache)338 repatchCall(exec->codeBlock(), stubInfo.callReturnLocation, operationGetById);363 if (tryCacheGetByID(exec, baseValue, propertyName, slot, stubInfo, kind) == GiveUpOnCache) 364 repatchCall(exec->codeBlock(), stubInfo.callReturnLocation, appropriateGenericGetByIdFunction(kind)); 339 365 } 340 366 … … 911 937 } 912 938 913 void resetGetByID(CodeBlock* codeBlock, StructureStubInfo& stubInfo )914 { 915 repatchCall(codeBlock, stubInfo.callReturnLocation, operationGetByIdOptimize);939 void resetGetByID(CodeBlock* codeBlock, StructureStubInfo& stubInfo, GetByIDKind kind) 940 { 941 repatchCall(codeBlock, stubInfo.callReturnLocation, appropriateOptimizingGetByIdFunction(kind)); 916 942 resetGetByIDCheckAndLoad(stubInfo); 917 943 MacroAssembler::repatchJump(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.patch.deltaCallToJump), stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase)); -
trunk/Source/JavaScriptCore/jit/Repatch.h
r199108 r199170 36 36 namespace JSC { 37 37 38 void repatchGetByID(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&); 38 enum class GetByIDKind { 39 Normal, 40 Pure 41 }; 42 43 void repatchGetByID(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&, GetByIDKind); 39 44 void buildGetByIDList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&); 40 45 void buildGetByIDProtoList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&); … … 47 52 void linkVirtualFor(ExecState*, CallLinkInfo&); 48 53 void linkPolymorphicCall(ExecState*, CallLinkInfo&, CallVariant); 49 void resetGetByID(CodeBlock*, StructureStubInfo& );54 void resetGetByID(CodeBlock*, StructureStubInfo&, GetByIDKind); 50 55 void resetPutByID(CodeBlock*, StructureStubInfo&); 51 56 void resetIn(CodeBlock*, StructureStubInfo&); -
trunk/Source/JavaScriptCore/jsc.cpp
r199164 r199170 24 24 25 25 #include "ArrayPrototype.h" 26 #include "BuiltinExecutableCreator.h" 26 27 #include "ButterflyInlines.h" 27 28 #include "BytecodeGenerator.h" … … 33 34 #include "Exception.h" 34 35 #include "ExceptionHelpers.h" 36 #include "GetterSetter.h" 35 37 #include "HeapProfiler.h" 36 38 #include "HeapSnapshotBuilder.h" … … 553 555 static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState*); 554 556 static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState*); 557 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState*); 555 558 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState*); 556 559 … … 573 576 static EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState*); 574 577 static EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState*); 578 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState*); 575 579 #ifndef NDEBUG 576 580 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState*); … … 744 748 addFunction(vm, "gcHeapSize", functionHeapSize, 0); 745 749 addFunction(vm, "addressOf", functionAddressOf, 1); 750 addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2); 746 751 #ifndef NDEBUG 747 752 addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0); … … 793 798 addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1); 794 799 addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0); 800 addFunction(vm, "createBuiltin", functionCreateBuiltin, 2); 795 801 addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2); 796 802 … … 1333 1339 } 1334 1340 1341 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState* exec) 1342 { 1343 JSValue value = exec->argument(0); 1344 if (!value.isObject()) 1345 return JSValue::encode(jsUndefined()); 1346 1347 JSValue property = exec->argument(1); 1348 if (!property.isString()) 1349 return JSValue::encode(jsUndefined()); 1350 1351 Identifier ident = Identifier::fromString(&exec->vm(), property.toString(exec)->value(exec)); 1352 1353 PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry); 1354 value.getPropertySlot(exec, ident, slot); 1355 1356 JSValue result; 1357 if (slot.isCacheableGetter()) 1358 result = slot.getterSetter(); 1359 else 1360 result = jsNull(); 1361 1362 return JSValue::encode(result); 1363 } 1364 1335 1365 EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*) 1336 1366 { … … 1720 1750 return JSValue::encode(exec->vm().throwException(exec, error)); 1721 1751 return JSValue::encode(jsUndefined()); 1752 } 1753 1754 EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState* exec) 1755 { 1756 if (exec->argumentCount() < 1 || !exec->argument(0).isString()) 1757 return JSValue::encode(jsUndefined()); 1758 1759 String functionText = exec->argument(0).toString(exec)->value(exec); 1760 if (exec->hadException()) 1761 return JSValue::encode(JSValue()); 1762 1763 VM& vm = exec->vm(); 1764 const SourceCode& source = makeSource(functionText); 1765 JSFunction* func = JSFunction::createBuiltinFunction(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, source), exec->lexicalGlobalObject()); 1766 1767 return JSValue::encode(func); 1722 1768 } 1723 1769 -
trunk/Source/JavaScriptCore/llint/LLIntData.cpp
r199108 r199170 145 145 STATIC_ASSERT(StringType == 6); 146 146 STATIC_ASSERT(SymbolType == 7); 147 STATIC_ASSERT(ObjectType == 2 1);148 STATIC_ASSERT(FinalObjectType == 2 2);149 STATIC_ASSERT(JSFunctionType == 2 4);147 STATIC_ASSERT(ObjectType == 20); 148 STATIC_ASSERT(FinalObjectType == 21); 149 STATIC_ASSERT(JSFunctionType == 23); 150 150 STATIC_ASSERT(MasqueradesAsUndefined == 1); 151 151 STATIC_ASSERT(ImplementsDefaultHasInstance == 2); -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r199108 r199170 546 546 } 547 547 548 LLINT_SLOW_PATH_DECL(slow_path_try_get_by_id) 549 { 550 LLINT_BEGIN(); 551 CodeBlock* codeBlock = exec->codeBlock(); 552 const Identifier& ident = codeBlock->identifier(pc[3].u.operand); 553 JSValue baseValue = LLINT_OP_C(2).jsValue(); 554 PropertySlot slot(baseValue, PropertySlot::PropertySlot::InternalMethodType::VMInquiry); 555 556 baseValue.getPropertySlot(exec, ident, slot); 557 558 LLINT_RETURN(slot.getPureResult()); 559 } 560 548 561 LLINT_SLOW_PATH_DECL(slow_path_get_by_id) 549 562 { -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r199108 r199170 70 70 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_instanceof); 71 71 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_instanceof_custom); 72 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_try_get_by_id); 72 73 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id); 73 74 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_arguments_length); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r199108 r199170 327 327 const StringType = 6 328 328 const SymbolType = 7 329 const ObjectType = 2 1330 const FinalObjectType = 2 2331 const JSFunctionType = 2 4329 const ObjectType = 20 330 const FinalObjectType = 21 331 const JSFunctionType = 23 332 332 333 333 # Type flags constants. … … 1302 1302 1303 1303 1304 _llint_op_try_get_by_id: 1305 traceExecution() 1306 callSlowPath(_llint_slow_path_try_get_by_id) 1307 dispatch(4) 1308 1309 1304 1310 _llint_op_del_by_id: 1305 1311 traceExecution() -
trunk/Source/JavaScriptCore/runtime/GetterSetter.cpp
r199108 r199170 34 34 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(GetterSetter); 35 35 36 const ClassInfo GetterSetter::s_info = { "GetterSetter", 0, 0, CREATE_METHOD_TABLE(GetterSetter) };36 const ClassInfo GetterSetter::s_info = { "GetterSetter", &Base::s_info, 0, CREATE_METHOD_TABLE(GetterSetter) }; 37 37 38 38 void GetterSetter::visitChildren(JSCell* cell, SlotVisitor& visitor) -
trunk/Source/JavaScriptCore/runtime/GetterSetter.h
r199108 r199170 42 42 // that constant is observed to have a non-null setter (or getter) then we can 43 43 // constant fold that setter (or getter). 44 class GetterSetter final : public JS Cell{44 class GetterSetter final : public JSNonFinalObject { 45 45 friend class JIT; 46 46 typedef JSNonFinalObject Base; 47 47 private: 48 48 GetterSetter(VM& vm, JSGlobalObject* globalObject) 49 : JSCell(vm, vm.getterSetterStructure.get())49 : Base(vm, vm.getterSetterStructure.get()) 50 50 { 51 51 m_getter.set(vm, this, globalObject->nullGetterFunction()); … … 54 54 55 55 public: 56 typedef JSCell Base; 57 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;56 57 static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | StructureIsImmortal; 58 58 59 59 static GetterSetter* create(VM& vm, JSGlobalObject* globalObject) … … 129 129 } 130 130 131 DECLARE_INFO; 131 DECLARE_EXPORT_INFO; 132 133 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&) { RELEASE_ASSERT_NOT_REACHED(); return false; } 134 static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&) { RELEASE_ASSERT_NOT_REACHED(); return false; } 135 static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool) { RELEASE_ASSERT_NOT_REACHED(); return false; } 136 static bool deleteProperty(JSCell*, ExecState*, PropertyName) { RELEASE_ASSERT_NOT_REACHED(); return false; } 132 137 133 138 private: -
trunk/Source/JavaScriptCore/runtime/JSType.h
r199164 r199170 36 36 SymbolType, 37 37 38 GetterSetterType,39 38 CustomGetterSetterType, 40 39 APIValueWrapperType, … … 76 75 DataViewType, 77 76 77 GetterSetterType, 78 78 GlobalObjectType, 79 79 LexicalEnvironmentType, -
trunk/Source/JavaScriptCore/runtime/PropertySlot.cpp
r199108 r199170 40 40 } 41 41 42 JSValue PropertySlot::getPureResult() const 43 { 44 JSValue result; 45 if (isTaintedByProxy()) 46 result = jsNull(); 47 else if (isCacheableValue()) 48 result = JSValue::decode(m_data.value); 49 else if (isCacheableGetter()) 50 result = getterSetter(); 51 else if (isUnset()) 52 result = jsUndefined(); 53 else 54 result = jsNull(); 55 56 return result; 57 } 58 42 59 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/PropertySlot.h
r199108 r199170 95 95 JSValue getValue(ExecState*, PropertyName) const; 96 96 JSValue getValue(ExecState*, unsigned propertyName) const; 97 JSValue getPureResult() const; 97 98 98 99 bool isCacheable() const { return m_cacheability == CachingAllowed && m_offset != invalidOffset; } -
trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp
r199108 r199170 333 333 { 334 334 slot.disableCaching(); 335 if (slot.internalMethodType() != PropertySlot::InternalMethodType::VMInquiry) 336 slot.setIsTaintedByProxy(); 335 slot.setIsTaintedByProxy(); 337 336 switch (slot.internalMethodType()) { 338 337 case PropertySlot::InternalMethodType::Get:
Note:
See TracChangeset
for help on using the changeset viewer.