Changeset 171605 in webkit
- Timestamp:
- Jul 25, 2014, 11:46:46 AM (11 years ago)
- Location:
- branches/ftlopt/Source
- Files:
-
- 12 added
- 71 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/ftlopt/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
r166493 r171605 517 517 StringImpl* name = it->key.get(); 518 518 StaticValueEntry* entry = it->value.get(); 519 if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)))519 if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || shouldIncludeDontEnumProperties(mode))) 520 520 propertyNames.add(Identifier(exec, name)); 521 521 } … … 528 528 StringImpl* name = it->key.get(); 529 529 StaticFunctionEntry* entry = it->value.get(); 530 if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))530 if (!(entry->attributes & kJSPropertyAttributeDontEnum) || shouldIncludeDontEnumProperties(mode)) 531 531 propertyNames.add(Identifier(exec, name)); 532 532 } -
branches/ftlopt/Source/JavaScriptCore/ChangeLog
r171510 r171605 1 2014-07-23 Mark Hahnenberg <[email protected]> 2 3 Refactor our current implementation of for-in 4 https://bugs.webkit.org/show_bug.cgi?id=134142 5 6 Reviewed by Filip Pizlo. 7 8 This patch splits for-in loops into three distinct parts: 9 10 - Iterating over the indexed properties in the base object. 11 - Iterating over the Structure properties in the base object. 12 - Iterating over any other enumerable properties for that object and any objects in the prototype chain. 13 14 It does this by emitting these explicit loops in bytecode, using a new set of bytecodes to 15 support the various operations required for each loop. 16 17 * API/JSCallbackObjectFunctions.h: 18 (JSC::JSCallbackObject<Parent>::getOwnNonIndexPropertyNames): 19 * JavaScriptCore.xcodeproj/project.pbxproj: 20 * bytecode/BytecodeList.json: 21 * bytecode/BytecodeUseDef.h: 22 (JSC::computeUsesForBytecodeOffset): 23 (JSC::computeDefsForBytecodeOffset): 24 * bytecode/CallLinkStatus.h: 25 (JSC::CallLinkStatus::CallLinkStatus): 26 * bytecode/CodeBlock.cpp: 27 (JSC::CodeBlock::dumpBytecode): 28 (JSC::CodeBlock::CodeBlock): 29 * bytecompiler/BytecodeGenerator.cpp: 30 (JSC::BytecodeGenerator::emitGetByVal): 31 (JSC::BytecodeGenerator::emitComplexPopScopes): 32 (JSC::BytecodeGenerator::emitGetEnumerableLength): 33 (JSC::BytecodeGenerator::emitHasGenericProperty): 34 (JSC::BytecodeGenerator::emitHasIndexedProperty): 35 (JSC::BytecodeGenerator::emitHasStructureProperty): 36 (JSC::BytecodeGenerator::emitGetStructurePropertyEnumerator): 37 (JSC::BytecodeGenerator::emitGetGenericPropertyEnumerator): 38 (JSC::BytecodeGenerator::emitNextEnumeratorPropertyName): 39 (JSC::BytecodeGenerator::emitToIndexString): 40 (JSC::BytecodeGenerator::pushIndexedForInScope): 41 (JSC::BytecodeGenerator::popIndexedForInScope): 42 (JSC::BytecodeGenerator::pushStructureForInScope): 43 (JSC::BytecodeGenerator::popStructureForInScope): 44 (JSC::BytecodeGenerator::invalidateForInContextForLocal): 45 * bytecompiler/BytecodeGenerator.h: 46 (JSC::ForInContext::ForInContext): 47 (JSC::ForInContext::~ForInContext): 48 (JSC::ForInContext::isValid): 49 (JSC::ForInContext::invalidate): 50 (JSC::ForInContext::local): 51 (JSC::StructureForInContext::StructureForInContext): 52 (JSC::StructureForInContext::type): 53 (JSC::StructureForInContext::index): 54 (JSC::StructureForInContext::property): 55 (JSC::StructureForInContext::enumerator): 56 (JSC::IndexedForInContext::IndexedForInContext): 57 (JSC::IndexedForInContext::type): 58 (JSC::IndexedForInContext::index): 59 (JSC::BytecodeGenerator::pushOptimisedForIn): Deleted. 60 (JSC::BytecodeGenerator::popOptimisedForIn): Deleted. 61 * bytecompiler/NodesCodegen.cpp: 62 (JSC::ReadModifyResolveNode::emitBytecode): 63 (JSC::AssignResolveNode::emitBytecode): 64 (JSC::ForInNode::tryGetBoundLocal): 65 (JSC::ForInNode::emitLoopHeader): 66 (JSC::ForInNode::emitMultiLoopBytecode): 67 (JSC::ForInNode::emitBytecode): 68 * debugger/DebuggerScope.h: 69 * dfg/DFGAbstractHeap.h: 70 * dfg/DFGAbstractInterpreterInlines.h: 71 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 72 * dfg/DFGByteCodeParser.cpp: 73 (JSC::DFG::ByteCodeParser::parseBlock): 74 * dfg/DFGCapabilities.cpp: 75 (JSC::DFG::capabilityLevel): 76 * dfg/DFGClobberize.h: 77 (JSC::DFG::clobberize): 78 * dfg/DFGDoesGC.cpp: 79 (JSC::DFG::doesGC): 80 * dfg/DFGFixupPhase.cpp: 81 (JSC::DFG::FixupPhase::fixupNode): 82 * dfg/DFGHeapLocation.cpp: 83 (WTF::printInternal): 84 * dfg/DFGHeapLocation.h: 85 * dfg/DFGNode.h: 86 (JSC::DFG::Node::hasHeapPrediction): 87 (JSC::DFG::Node::hasArrayMode): 88 * dfg/DFGNodeType.h: 89 * dfg/DFGPredictionPropagationPhase.cpp: 90 (JSC::DFG::PredictionPropagationPhase::propagate): 91 * dfg/DFGSafeToExecute.h: 92 (JSC::DFG::safeToExecute): 93 * dfg/DFGSpeculativeJIT.h: 94 (JSC::DFG::SpeculativeJIT::callOperation): 95 * dfg/DFGSpeculativeJIT32_64.cpp: 96 (JSC::DFG::SpeculativeJIT::compile): 97 * dfg/DFGSpeculativeJIT64.cpp: 98 (JSC::DFG::SpeculativeJIT::compile): 99 * jit/JIT.cpp: 100 (JSC::JIT::privateCompileMainPass): 101 (JSC::JIT::privateCompileSlowCases): 102 * jit/JIT.h: 103 (JSC::JIT::compileHasIndexedProperty): 104 (JSC::JIT::emitInt32Load): 105 * jit/JITInlines.h: 106 (JSC::JIT::emitDoubleGetByVal): 107 (JSC::JIT::emitLoadForArrayMode): 108 (JSC::JIT::emitContiguousGetByVal): 109 (JSC::JIT::emitArrayStorageGetByVal): 110 * jit/JITOpcodes.cpp: 111 (JSC::JIT::emit_op_get_enumerable_length): 112 (JSC::JIT::emit_op_has_structure_property): 113 (JSC::JIT::emitSlow_op_has_structure_property): 114 (JSC::JIT::emit_op_has_generic_property): 115 (JSC::JIT::privateCompileHasIndexedProperty): 116 (JSC::JIT::emit_op_has_indexed_property): 117 (JSC::JIT::emitSlow_op_has_indexed_property): 118 (JSC::JIT::emit_op_get_direct_pname): 119 (JSC::JIT::emitSlow_op_get_direct_pname): 120 (JSC::JIT::emit_op_get_structure_property_enumerator): 121 (JSC::JIT::emit_op_get_generic_property_enumerator): 122 (JSC::JIT::emit_op_next_enumerator_pname): 123 (JSC::JIT::emit_op_to_index_string): 124 * jit/JITOpcodes32_64.cpp: 125 (JSC::JIT::emit_op_get_enumerable_length): 126 (JSC::JIT::emit_op_has_structure_property): 127 (JSC::JIT::emitSlow_op_has_structure_property): 128 (JSC::JIT::emit_op_has_generic_property): 129 (JSC::JIT::privateCompileHasIndexedProperty): 130 (JSC::JIT::emit_op_has_indexed_property): 131 (JSC::JIT::emitSlow_op_has_indexed_property): 132 (JSC::JIT::emit_op_get_direct_pname): 133 (JSC::JIT::emitSlow_op_get_direct_pname): 134 (JSC::JIT::emit_op_get_structure_property_enumerator): 135 (JSC::JIT::emit_op_get_generic_property_enumerator): 136 (JSC::JIT::emit_op_next_enumerator_pname): 137 (JSC::JIT::emit_op_to_index_string): 138 * jit/JITOperations.cpp: 139 * jit/JITOperations.h: 140 * jit/JITPropertyAccess.cpp: 141 (JSC::JIT::emitDoubleLoad): 142 (JSC::JIT::emitContiguousLoad): 143 (JSC::JIT::emitArrayStorageLoad): 144 (JSC::JIT::emitDoubleGetByVal): Deleted. 145 (JSC::JIT::emitContiguousGetByVal): Deleted. 146 (JSC::JIT::emitArrayStorageGetByVal): Deleted. 147 * jit/JITPropertyAccess32_64.cpp: 148 (JSC::JIT::emitContiguousLoad): 149 (JSC::JIT::emitDoubleLoad): 150 (JSC::JIT::emitArrayStorageLoad): 151 (JSC::JIT::emitContiguousGetByVal): Deleted. 152 (JSC::JIT::emitDoubleGetByVal): Deleted. 153 (JSC::JIT::emitArrayStorageGetByVal): Deleted. 154 * llint/LowLevelInterpreter.asm: 155 * parser/Nodes.h: 156 * runtime/Arguments.cpp: 157 (JSC::Arguments::getOwnPropertyNames): 158 * runtime/ClassInfo.h: 159 * runtime/CommonSlowPaths.cpp: 160 (JSC::SLOW_PATH_DECL): 161 * runtime/CommonSlowPaths.h: 162 * runtime/EnumerationMode.h: Added. 163 (JSC::shouldIncludeDontEnumProperties): 164 (JSC::shouldExcludeDontEnumProperties): 165 (JSC::shouldIncludeJSObjectPropertyNames): 166 (JSC::modeThatSkipsJSObject): 167 * runtime/JSActivation.cpp: 168 (JSC::JSActivation::getOwnNonIndexPropertyNames): 169 * runtime/JSArray.cpp: 170 (JSC::JSArray::getOwnNonIndexPropertyNames): 171 * runtime/JSArrayBuffer.cpp: 172 (JSC::JSArrayBuffer::getOwnNonIndexPropertyNames): 173 * runtime/JSArrayBufferView.cpp: 174 (JSC::JSArrayBufferView::getOwnNonIndexPropertyNames): 175 * runtime/JSCell.cpp: 176 (JSC::JSCell::getEnumerableLength): 177 (JSC::JSCell::getStructurePropertyNames): 178 (JSC::JSCell::getGenericPropertyNames): 179 * runtime/JSCell.h: 180 * runtime/JSFunction.cpp: 181 (JSC::JSFunction::getOwnNonIndexPropertyNames): 182 * runtime/JSGenericTypedArrayViewInlines.h: 183 (JSC::JSGenericTypedArrayView<Adaptor>::getOwnNonIndexPropertyNames): 184 * runtime/JSObject.cpp: 185 (JSC::getClassPropertyNames): 186 (JSC::JSObject::hasOwnProperty): 187 (JSC::JSObject::getOwnPropertyNames): 188 (JSC::JSObject::getOwnNonIndexPropertyNames): 189 (JSC::JSObject::getEnumerableLength): 190 (JSC::JSObject::getStructurePropertyNames): 191 (JSC::JSObject::getGenericPropertyNames): 192 * runtime/JSObject.h: 193 * runtime/JSPropertyNameEnumerator.cpp: Added. 194 (JSC::JSPropertyNameEnumerator::create): 195 (JSC::JSPropertyNameEnumerator::JSPropertyNameEnumerator): 196 (JSC::JSPropertyNameEnumerator::finishCreation): 197 (JSC::JSPropertyNameEnumerator::destroy): 198 (JSC::JSPropertyNameEnumerator::visitChildren): 199 * runtime/JSPropertyNameEnumerator.h: Added. 200 (JSC::JSPropertyNameEnumerator::createStructure): 201 (JSC::JSPropertyNameEnumerator::propertyNameAtIndex): 202 (JSC::JSPropertyNameEnumerator::identifierSet): 203 (JSC::JSPropertyNameEnumerator::cachedPrototypeChain): 204 (JSC::JSPropertyNameEnumerator::setCachedPrototypeChain): 205 (JSC::JSPropertyNameEnumerator::cachedStructure): 206 (JSC::JSPropertyNameEnumerator::cachedStructureID): 207 (JSC::JSPropertyNameEnumerator::cachedInlineCapacity): 208 (JSC::JSPropertyNameEnumerator::cachedStructureIDOffset): 209 (JSC::JSPropertyNameEnumerator::cachedInlineCapacityOffset): 210 (JSC::JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset): 211 (JSC::JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset): 212 (JSC::structurePropertyNameEnumerator): 213 (JSC::genericPropertyNameEnumerator): 214 * runtime/JSProxy.cpp: 215 (JSC::JSProxy::getEnumerableLength): 216 (JSC::JSProxy::getStructurePropertyNames): 217 (JSC::JSProxy::getGenericPropertyNames): 218 * runtime/JSProxy.h: 219 * runtime/JSSymbolTableObject.cpp: 220 (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames): 221 * runtime/PropertyNameArray.cpp: 222 (JSC::PropertyNameArray::add): 223 (JSC::PropertyNameArray::setPreviouslyEnumeratedProperties): 224 * runtime/PropertyNameArray.h: 225 (JSC::RefCountedIdentifierSet::contains): 226 (JSC::RefCountedIdentifierSet::size): 227 (JSC::RefCountedIdentifierSet::add): 228 (JSC::PropertyNameArray::PropertyNameArray): 229 (JSC::PropertyNameArray::add): 230 (JSC::PropertyNameArray::addKnownUnique): 231 (JSC::PropertyNameArray::identifierSet): 232 (JSC::PropertyNameArray::canAddKnownUniqueForStructure): 233 (JSC::PropertyNameArray::setPreviouslyEnumeratedLength): 234 * runtime/RegExpObject.cpp: 235 (JSC::RegExpObject::getOwnNonIndexPropertyNames): 236 (JSC::RegExpObject::getPropertyNames): 237 (JSC::RegExpObject::getGenericPropertyNames): 238 * runtime/RegExpObject.h: 239 * runtime/StringObject.cpp: 240 (JSC::StringObject::getOwnPropertyNames): 241 * runtime/Structure.cpp: 242 (JSC::Structure::getPropertyNamesFromStructure): 243 (JSC::Structure::setCachedStructurePropertyNameEnumerator): 244 (JSC::Structure::cachedStructurePropertyNameEnumerator): 245 (JSC::Structure::setCachedGenericPropertyNameEnumerator): 246 (JSC::Structure::cachedGenericPropertyNameEnumerator): 247 (JSC::Structure::canCacheStructurePropertyNameEnumerator): 248 (JSC::Structure::canCacheGenericPropertyNameEnumerator): 249 (JSC::Structure::canAccessPropertiesQuickly): 250 * runtime/Structure.h: 251 * runtime/StructureRareData.cpp: 252 (JSC::StructureRareData::visitChildren): 253 (JSC::StructureRareData::cachedStructurePropertyNameEnumerator): 254 (JSC::StructureRareData::setCachedStructurePropertyNameEnumerator): 255 (JSC::StructureRareData::cachedGenericPropertyNameEnumerator): 256 (JSC::StructureRareData::setCachedGenericPropertyNameEnumerator): 257 * runtime/StructureRareData.h: 258 * runtime/VM.cpp: 259 (JSC::VM::VM): 260 * runtime/VM.h: 261 1 262 2014-07-23 Saam Barati <[email protected]> 2 263 -
branches/ftlopt/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r171510 r171605 816 816 2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */; }; 817 817 2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */ = {isa = PBXBuildFile; fileRef = 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */; }; 818 2A05ABD51961DF2400341750 /* JSPropertyNameEnumerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A05ABD31961DF2400341750 /* JSPropertyNameEnumerator.cpp */; }; 819 2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */; }; 818 820 2A2825D018341F2D0087FBA9 /* DelayedReleaseScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */; }; 819 821 2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = C211B574176A224D000E2A23 /* APICallbackFunction.h */; }; … … 839 841 2ACCF3DE185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACCF3DC185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.cpp */; }; 840 842 2ACCF3DF185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACCF3DD185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.h */; }; 843 2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD2EDFA19799E38004D6478 /* EnumerationMode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 841 844 2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AD8932917E3868F00668276 /* HeapIterationScope.h */; }; 842 845 2ADFA26318EF3540004F9FCC /* GCLogging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ADFA26218EF3540004F9FCC /* GCLogging.cpp */; }; … … 2970 2973 2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringJoiner.cpp; sourceTree = "<group>"; }; 2971 2974 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringJoiner.h; sourceTree = "<group>"; }; 2975 2A05ABD31961DF2400341750 /* JSPropertyNameEnumerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPropertyNameEnumerator.cpp; sourceTree = "<group>"; }; 2976 2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameEnumerator.h; sourceTree = "<group>"; }; 2972 2977 2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DelayedReleaseScope.h; sourceTree = "<group>"; }; 2973 2978 2A343F7418A1748B0039B085 /* GCSegmentedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCSegmentedArray.h; sourceTree = "<group>"; }; … … 2994 2999 2ACCF3DC185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStoreBarrierElisionPhase.cpp; path = dfg/DFGStoreBarrierElisionPhase.cpp; sourceTree = "<group>"; }; 2995 3000 2ACCF3DD185FE26B0083E2AD /* DFGStoreBarrierElisionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStoreBarrierElisionPhase.h; path = dfg/DFGStoreBarrierElisionPhase.h; sourceTree = "<group>"; }; 3001 2AD2EDFA19799E38004D6478 /* EnumerationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EnumerationMode.h; sourceTree = "<group>"; }; 2996 3002 2AD8932917E3868F00668276 /* HeapIterationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapIterationScope.h; sourceTree = "<group>"; }; 2997 3003 2ADFA26218EF3540004F9FCC /* GCLogging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCLogging.cpp; sourceTree = "<group>"; }; … … 4992 4998 A7DCB77912E3D90500911940 /* WriteBarrier.h */, 4993 4999 C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */, 5000 2A05ABD31961DF2400341750 /* JSPropertyNameEnumerator.cpp */, 5001 2A05ABD41961DF2400341750 /* JSPropertyNameEnumerator.h */, 5002 2AD2EDFA19799E38004D6478 /* EnumerationMode.h */, 4994 5003 ); 4995 5004 path = runtime; … … 5958 5967 A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */, 5959 5968 86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */, 5969 2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */, 5960 5970 52DAD38F195A164E00F30464 /* TypeLocation.h in Headers */, 5961 5971 52FB72151953760C00BB612E /* TypeSet.h in Headers */, … … 6617 6627 0FF729BC166AD360000F5BA3 /* ProfilerCompiledBytecode.h in Headers */, 6618 6628 0FF729BD166AD360000F5BA3 /* ProfilerDatabase.h in Headers */, 6629 2A05ABD61961DF2400341750 /* JSPropertyNameEnumerator.h in Headers */, 6619 6630 52B311011975B4670080857C /* TypeLocationCache.h in Headers */, 6620 6631 0FF729BE166AD360000F5BA3 /* ProfilerExecutionCounter.h in Headers */, … … 7766 7777 86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */, 7767 7778 A7D89CFF17A0B8CC00773AD8 /* DFGSSAConversionPhase.cpp in Sources */, 7779 2A05ABD51961DF2400341750 /* JSPropertyNameEnumerator.cpp in Sources */, 7768 7780 0FC20CB918556A3500C9E954 /* DFGSSALoweringPhase.cpp in Sources */, 7769 7781 0F9FB4F417FCB91700CB67F8 /* DFGStackLayoutPhase.cpp in Sources */, -
branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeList.json
r170836 r171605 126 126 { "name" : "op_profile_did_call", "length" : 2 }, 127 127 { "name" : "op_end", "length" : 2 }, 128 { "name" : "op_profile_types_with_high_fidelity", "length" : 4 } 128 { "name" : "op_profile_types_with_high_fidelity", "length" : 4 }, 129 { "name" : "op_get_enumerable_length", "length" : 3 }, 130 { "name" : "op_has_indexed_property", "length" : 5 }, 131 { "name" : "op_has_structure_property", "length" : 5 }, 132 { "name" : "op_has_generic_property", "length" : 4 }, 133 { "name" : "op_get_direct_pname", "length" : 7 }, 134 { "name" : "op_get_structure_property_enumerator", "length" : 4 }, 135 { "name" : "op_get_generic_property_enumerator", "length" : 5 }, 136 { "name" : "op_next_enumerator_pname", "length" : 4 }, 137 { "name" : "op_to_index_string", "length" : 3 } 129 138 ] 130 139 }, -
branches/ftlopt/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r170836 r171605 119 119 return; 120 120 } 121 case op_get_enumerable_length: 122 case op_to_index_string: 121 123 case op_init_global_const_nop: 122 124 case op_init_global_const: … … 151 153 return; 152 154 } 155 case op_has_generic_property: 156 case op_get_structure_property_enumerator: 157 case op_has_indexed_property: 158 case op_next_enumerator_pname: 153 159 case op_get_by_val: 154 160 case op_get_argument_by_val: … … 180 186 return; 181 187 } 188 case op_has_structure_property: 189 case op_get_generic_property_enumerator: 182 190 case op_construct_varargs: 183 191 case op_call_varargs: { … … 187 195 return; 188 196 } 197 case op_get_direct_pname: 189 198 case op_next_pname: { 190 199 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand); … … 299 308 return; 300 309 // These all have a single destination for the first argument. 310 case op_to_index_string: 311 case op_get_generic_property_enumerator: 312 case op_get_enumerable_length: 313 case op_has_indexed_property: 314 case op_has_structure_property: 315 case op_has_generic_property: 316 case op_get_direct_pname: 317 case op_get_structure_property_enumerator: 318 case op_next_enumerator_pname: 301 319 case op_next_pname: 302 320 case op_resolve_scope: -
branches/ftlopt/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r171510 r171605 1400 1400 break; 1401 1401 } 1402 case op_get_enumerable_length: { 1403 int dst = it[1].u.operand; 1404 int base = it[2].u.operand; 1405 printLocationAndOp(out, exec, location, it, "op_get_enumerable_length"); 1406 out.printf("%s, %s", registerName(dst).data(), registerName(base).data()); 1407 it += OPCODE_LENGTH(op_get_enumerable_length) - 1; 1408 break; 1409 } 1410 case op_has_indexed_property: { 1411 int dst = it[1].u.operand; 1412 int base = it[2].u.operand; 1413 int propertyName = it[3].u.operand; 1414 ArrayProfile* arrayProfile = it[4].u.arrayProfile; 1415 printLocationAndOp(out, exec, location, it, "op_has_indexed_property"); 1416 out.printf("%s, %s, %s, %p", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), arrayProfile); 1417 it += OPCODE_LENGTH(op_has_indexed_property) - 1; 1418 break; 1419 } 1420 case op_has_structure_property: { 1421 int dst = it[1].u.operand; 1422 int base = it[2].u.operand; 1423 int propertyName = it[3].u.operand; 1424 int enumerator = it[4].u.operand; 1425 printLocationAndOp(out, exec, location, it, "op_has_structure_property"); 1426 out.printf("%s, %s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), registerName(enumerator).data()); 1427 it += OPCODE_LENGTH(op_has_structure_property) - 1; 1428 break; 1429 } 1430 case op_has_generic_property: { 1431 int dst = it[1].u.operand; 1432 int base = it[2].u.operand; 1433 int propertyName = it[3].u.operand; 1434 printLocationAndOp(out, exec, location, it, "op_has_generic_property"); 1435 out.printf("%s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data()); 1436 it += OPCODE_LENGTH(op_has_generic_property) - 1; 1437 break; 1438 } 1439 case op_get_direct_pname: { 1440 int dst = it[1].u.operand; 1441 int base = it[2].u.operand; 1442 int propertyName = it[3].u.operand; 1443 int index = it[4].u.operand; 1444 int enumerator = it[5].u.operand; 1445 ValueProfile* profile = it[6].u.profile; 1446 printLocationAndOp(out, exec, location, it, "op_get_direct_pname"); 1447 out.printf("%s, %s, %s, %s, %s, %p", registerName(dst).data(), registerName(base).data(), registerName(propertyName).data(), registerName(index).data(), registerName(enumerator).data(), profile); 1448 it += OPCODE_LENGTH(op_get_direct_pname) - 1; 1449 break; 1450 1451 } 1452 case op_get_structure_property_enumerator: { 1453 int dst = it[1].u.operand; 1454 int base = it[2].u.operand; 1455 printLocationAndOp(out, exec, location, it, "op_get_structure_property_enumerator"); 1456 out.printf("%s, %s", registerName(dst).data(), registerName(base).data()); 1457 it += OPCODE_LENGTH(op_get_structure_property_enumerator) - 1; 1458 break; 1459 } 1460 case op_get_generic_property_enumerator: { 1461 int dst = it[1].u.operand; 1462 int base = it[2].u.operand; 1463 int length = it[3].u.operand; 1464 int structureEnumerator = it[4].u.operand; 1465 printLocationAndOp(out, exec, location, it, "op_get_generic_property_enumerator"); 1466 out.printf("%s, %s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(length).data(), registerName(structureEnumerator).data()); 1467 it += OPCODE_LENGTH(op_get_generic_property_enumerator) - 1; 1468 break; 1469 } 1470 case op_next_enumerator_pname: { 1471 int dst = it[1].u.operand; 1472 int enumerator = it[2].u.operand; 1473 int index = it[3].u.operand; 1474 printLocationAndOp(out, exec, location, it, "op_next_enumerator_pname"); 1475 out.printf("%s, %s, %s", registerName(dst).data(), registerName(enumerator).data(), registerName(index).data()); 1476 it += OPCODE_LENGTH(op_next_enumerator_pname) - 1; 1477 break; 1478 } 1479 case op_to_index_string: { 1480 int dst = it[1].u.operand; 1481 int index = it[2].u.operand; 1482 printLocationAndOp(out, exec, location, it, "op_to_index_string"); 1483 out.printf("%s, %s", registerName(dst).data(), registerName(index).data()); 1484 it += OPCODE_LENGTH(op_to_index_string) - 1; 1485 break; 1486 } 1402 1487 case op_push_with_scope: { 1403 1488 int r0 = (++it)->u.operand; … … 1807 1892 } 1808 1893 switch (pc[0].u.opcode) { 1894 case op_has_indexed_property: { 1895 int arrayProfileIndex = pc[opLength - 1].u.operand; 1896 m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i); 1897 1898 instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex]; 1899 break; 1900 } 1809 1901 case op_call_varargs: 1810 1902 case op_construct_varargs: … … 1817 1909 FALLTHROUGH; 1818 1910 } 1911 case op_get_direct_pname: 1819 1912 case op_get_by_id: { 1820 1913 ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand]; -
branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r171510 r171605 1445 1445 { 1446 1446 for (size_t i = m_forInContextStack.size(); i > 0; i--) { 1447 ForInContext& context = m_forInContextStack[i - 1]; 1448 if (context.propertyRegister == property) { 1449 emitOpcode(op_get_by_pname); 1450 instructions().append(dst->index()); 1451 instructions().append(base->index()); 1452 instructions().append(property->index()); 1453 instructions().append(context.expectedSubscriptRegister->index()); 1454 instructions().append(context.iterRegister->index()); 1455 instructions().append(context.indexRegister->index()); 1456 return dst; 1457 } 1458 } 1447 ForInContext* context = m_forInContextStack[i - 1].get(); 1448 if (context->local() != property) 1449 continue; 1450 1451 if (!context->isValid()) 1452 break; 1453 1454 if (context->type() == ForInContext::IndexedForInContextType) { 1455 property = static_cast<IndexedForInContext*>(context)->index(); 1456 break; 1457 } 1458 1459 ASSERT(context->type() == ForInContext::StructureForInContextType); 1460 StructureForInContext* structureContext = static_cast<StructureForInContext*>(context); 1461 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_direct_pname); 1462 instructions().append(kill(dst)); 1463 instructions().append(base->index()); 1464 instructions().append(property->index()); 1465 instructions().append(structureContext->index()->index()); 1466 instructions().append(structureContext->enumerator()->index()); 1467 instructions().append(profile); 1468 return dst; 1469 } 1470 1459 1471 UnlinkedArrayProfile arrayProfile = newArrayProfile(); 1460 1472 UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val); … … 2170 2182 Vector<ControlFlowContext> savedScopeContextStack; 2171 2183 Vector<SwitchInfo> savedSwitchContextStack; 2172 Vector< ForInContext> savedForInContextStack;2184 Vector<std::unique_ptr<ForInContext>> savedForInContextStack; 2173 2185 Vector<TryContext> poppedTryContexts; 2174 2186 LabelScopeStore savedLabelScopes; … … 2197 2209 } 2198 2210 if (flipForIns) { 2199 savedForInContextStack = m_forInContextStack;2211 savedForInContextStack.swap(m_forInContextStack); 2200 2212 m_forInContextStack.shrink(finallyContext.forInContextStackSize); 2201 2213 } … … 2237 2249 m_switchContextStack = savedSwitchContextStack; 2238 2250 if (flipForIns) 2239 m_forInContextStack = savedForInContextStack;2251 m_forInContextStack.swap(savedForInContextStack); 2240 2252 if (flipTries) { 2241 2253 ASSERT(m_tryContextStack.size() == finallyContext.tryContextStackSize); … … 2570 2582 } 2571 2583 2584 RegisterID* BytecodeGenerator::emitGetEnumerableLength(RegisterID* dst, RegisterID* base) 2585 { 2586 emitOpcode(op_get_enumerable_length); 2587 instructions().append(dst->index()); 2588 instructions().append(base->index()); 2589 return dst; 2590 } 2591 2592 RegisterID* BytecodeGenerator::emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName) 2593 { 2594 emitOpcode(op_has_generic_property); 2595 instructions().append(dst->index()); 2596 instructions().append(base->index()); 2597 instructions().append(propertyName->index()); 2598 return dst; 2599 } 2600 2601 RegisterID* BytecodeGenerator::emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName) 2602 { 2603 UnlinkedArrayProfile arrayProfile = newArrayProfile(); 2604 emitOpcode(op_has_indexed_property); 2605 instructions().append(dst->index()); 2606 instructions().append(base->index()); 2607 instructions().append(propertyName->index()); 2608 instructions().append(arrayProfile); 2609 return dst; 2610 } 2611 2612 RegisterID* BytecodeGenerator::emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator) 2613 { 2614 emitOpcode(op_has_structure_property); 2615 instructions().append(dst->index()); 2616 instructions().append(base->index()); 2617 instructions().append(propertyName->index()); 2618 instructions().append(enumerator->index()); 2619 return dst; 2620 } 2621 2622 RegisterID* BytecodeGenerator::emitGetStructurePropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length) 2623 { 2624 emitOpcode(op_get_structure_property_enumerator); 2625 instructions().append(dst->index()); 2626 instructions().append(base->index()); 2627 instructions().append(length->index()); 2628 return dst; 2629 } 2630 2631 RegisterID* BytecodeGenerator::emitGetGenericPropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length, RegisterID* structureEnumerator) 2632 { 2633 emitOpcode(op_get_generic_property_enumerator); 2634 instructions().append(dst->index()); 2635 instructions().append(base->index()); 2636 instructions().append(length->index()); 2637 instructions().append(structureEnumerator->index()); 2638 return dst; 2639 } 2640 2641 RegisterID* BytecodeGenerator::emitNextEnumeratorPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index) 2642 { 2643 emitOpcode(op_next_enumerator_pname); 2644 instructions().append(dst->index()); 2645 instructions().append(enumerator->index()); 2646 instructions().append(index->index()); 2647 return dst; 2648 } 2649 2650 RegisterID* BytecodeGenerator::emitToIndexString(RegisterID* dst, RegisterID* index) 2651 { 2652 emitOpcode(op_to_index_string); 2653 instructions().append(dst->index()); 2654 instructions().append(index->index()); 2655 return dst; 2656 } 2657 2658 void BytecodeGenerator::pushIndexedForInScope(RegisterID* localRegister, RegisterID* indexRegister) 2659 { 2660 if (!localRegister) 2661 return; 2662 m_forInContextStack.append(std::make_unique<IndexedForInContext>(localRegister, indexRegister)); 2663 } 2664 2665 void BytecodeGenerator::popIndexedForInScope(RegisterID* localRegister) 2666 { 2667 if (!localRegister) 2668 return; 2669 m_forInContextStack.removeLast(); 2670 } 2671 2672 void BytecodeGenerator::pushStructureForInScope(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister) 2673 { 2674 if (!localRegister) 2675 return; 2676 m_forInContextStack.append(std::make_unique<StructureForInContext>(localRegister, indexRegister, propertyRegister, enumeratorRegister)); 2677 } 2678 2679 void BytecodeGenerator::popStructureForInScope(RegisterID* localRegister) 2680 { 2681 if (!localRegister) 2682 return; 2683 m_forInContextStack.removeLast(); 2684 } 2685 2686 void BytecodeGenerator::invalidateForInContextForLocal(RegisterID* localRegister) 2687 { 2688 // Lexically invalidating ForInContexts is kind of weak sauce, but it only occurs if 2689 // either of the following conditions is true: 2690 // 2691 // (1) The loop iteration variable is re-assigned within the body of the loop. 2692 // (2) The loop iteration variable is captured in the lexical scope of the function. 2693 // 2694 // These two situations occur sufficiently rarely that it's okay to use this style of 2695 // "analysis" to make iteration faster. If we didn't want to do this, we would either have 2696 // to perform some flow-sensitive analysis to see if/when the loop iteration variable was 2697 // reassigned, or we'd have to resort to runtime checks to see if the variable had been 2698 // reassigned from its original value. 2699 for (size_t i = m_forInContextStack.size(); i > 0; i--) { 2700 ForInContext* context = m_forInContextStack[i - 1].get(); 2701 if (context->local() != localRegister) 2702 continue; 2703 context->invalidate(); 2704 break; 2705 } 2706 } 2707 2572 2708 } // namespace JSC -
branches/ftlopt/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r171510 r171605 98 98 }; 99 99 100 struct ForInContext { 101 RefPtr<RegisterID> expectedSubscriptRegister; 102 RefPtr<RegisterID> iterRegister; 103 RefPtr<RegisterID> indexRegister; 104 RefPtr<RegisterID> propertyRegister; 100 class ForInContext { 101 public: 102 ForInContext(RegisterID* localRegister) 103 : m_localRegister(localRegister) 104 , m_isValid(true) 105 { 106 } 107 108 virtual ~ForInContext() 109 { 110 } 111 112 bool isValid() const { return m_isValid; } 113 void invalidate() { m_isValid = false; } 114 115 enum ForInContextType { 116 StructureForInContextType, 117 IndexedForInContextType 118 }; 119 virtual ForInContextType type() const = 0; 120 121 RegisterID* local() const { return m_localRegister.get(); } 122 123 private: 124 RefPtr<RegisterID> m_localRegister; 125 bool m_isValid; 126 }; 127 128 class StructureForInContext : public ForInContext { 129 public: 130 StructureForInContext(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister) 131 : ForInContext(localRegister) 132 , m_indexRegister(indexRegister) 133 , m_propertyRegister(propertyRegister) 134 , m_enumeratorRegister(enumeratorRegister) 135 { 136 } 137 138 virtual ForInContextType type() const 139 { 140 return StructureForInContextType; 141 } 142 143 RegisterID* index() const { return m_indexRegister.get(); } 144 RegisterID* property() const { return m_propertyRegister.get(); } 145 RegisterID* enumerator() const { return m_enumeratorRegister.get(); } 146 147 private: 148 RefPtr<RegisterID> m_indexRegister; 149 RefPtr<RegisterID> m_propertyRegister; 150 RefPtr<RegisterID> m_enumeratorRegister; 151 }; 152 153 class IndexedForInContext : public ForInContext { 154 public: 155 IndexedForInContext(RegisterID* localRegister, RegisterID* indexRegister) 156 : ForInContext(localRegister) 157 , m_indexRegister(indexRegister) 158 { 159 } 160 161 virtual ForInContextType type() const 162 { 163 return IndexedForInContextType; 164 } 165 166 RegisterID* index() const { return m_indexRegister.get(); } 167 168 private: 169 RefPtr<RegisterID> m_indexRegister; 105 170 }; 106 171 … … 426 491 RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target); 427 492 493 RegisterID* emitHasIndexedProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName); 494 RegisterID* emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator); 495 RegisterID* emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName); 496 RegisterID* emitGetEnumerableLength(RegisterID* dst, RegisterID* base); 497 RegisterID* emitGetStructurePropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length); 498 RegisterID* emitGetGenericPropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length, RegisterID* structureEnumerator); 499 RegisterID* emitNextEnumeratorPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index); 500 RegisterID* emitToIndexString(RegisterID* dst, RegisterID* index); 501 428 502 void emitReadOnlyExceptionIfNeeded(); 429 503 … … 455 529 void popFinallyContext(); 456 530 457 void pushOptimisedForIn(RegisterID* expectedSubscript, RegisterID* iter, RegisterID* index, RegisterID* propertyRegister) 458 { 459 ForInContext context = { expectedSubscript, iter, index, propertyRegister }; 460 m_forInContextStack.append(context); 461 } 462 463 void popOptimisedForIn() 464 { 465 m_forInContextStack.removeLast(); 466 } 531 void pushIndexedForInScope(RegisterID* local, RegisterID* index); 532 void popIndexedForInScope(RegisterID* local); 533 void pushStructureForInScope(RegisterID* local, RegisterID* index, RegisterID* property, RegisterID* enumerator); 534 void popStructureForInScope(RegisterID* local); 535 void invalidateForInContextForLocal(RegisterID* local); 467 536 468 537 LabelScopePtr breakTarget(const Identifier&); … … 663 732 Vector<ControlFlowContext, 0, UnsafeVectorOverflow> m_scopeContextStack; 664 733 Vector<SwitchInfo> m_switchContextStack; 665 Vector< ForInContext> m_forInContextStack;734 Vector<std::unique_ptr<ForInContext>> m_forInContextStack; 666 735 Vector<TryContext> m_tryContextStack; 667 736 Vector<std::pair<RefPtr<RegisterID>, const DeconstructionPatternNode*>> m_deconstructedParameters; -
branches/ftlopt/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r170836 r171605 1506 1506 emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1507 1507 generator.emitMove(local.get(), result.get()); 1508 generator.invalidateForInContextForLocal(local.get()); 1508 1509 if (generator.isProfilingTypesWithHighFidelity()) 1509 1510 generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd()); … … 1512 1513 1513 1514 RegisterID* result = emitReadModifyAssignment(generator, local.get(), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1515 generator.invalidateForInContextForLocal(local.get()); 1514 1516 return generator.moveToDestinationIfNeeded(dst, result); 1515 1517 } … … 1541 1543 generator.emitNode(tempDst.get(), m_right); 1542 1544 generator.emitMove(local.get(), tempDst.get()); 1545 generator.invalidateForInContextForLocal(local.get()); 1543 1546 if (generator.isProfilingTypesWithHighFidelity()) 1544 1547 generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd()); … … 1546 1549 } 1547 1550 RegisterID* result = generator.emitNode(local.get(), m_right); 1551 generator.invalidateForInContextForLocal(local.get()); 1548 1552 return generator.moveToDestinationIfNeeded(dst, result); 1549 1553 } … … 1921 1925 // ------------------------------ ForInNode ------------------------------------ 1922 1926 1923 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1924 { 1925 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop); 1926 1927 if (!m_lexpr->isAssignmentLocation()) { 1928 emitThrowReferenceError(generator, "Left side of for-in statement is not a reference."); 1929 return; 1930 } 1931 1932 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset()); 1933 1934 RefPtr<RegisterID> base = generator.newTemporary(); 1935 generator.emitNode(base.get(), m_expr); 1936 RefPtr<RegisterID> i = generator.newTemporary(); 1937 RefPtr<RegisterID> size = generator.newTemporary(); 1938 RefPtr<RegisterID> expectedSubscript; 1939 RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget()); 1940 generator.emitJump(scope->continueTarget()); 1941 1942 RefPtr<Label> loopStart = generator.newLabel(); 1943 generator.emitLabel(loopStart.get()); 1944 generator.emitLoopHint(); 1945 1946 RegisterID* propertyName; 1947 bool optimizedForinAccess = false; 1927 RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator) 1928 { 1948 1929 if (m_lexpr->isResolveNode()) { 1949 1930 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); 1950 1931 Local local = generator.local(ident); 1951 if (!local.get()) { 1952 propertyName = generator.newTemporary(); 1953 RefPtr<RegisterID> protect = propertyName; 1932 if (local.isCaptured()) 1933 return nullptr; 1934 return local.get(); 1935 } 1936 1937 if (m_lexpr->isDeconstructionNode()) { 1938 DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr); 1939 auto binding = assignNode->bindings(); 1940 if (!binding->isBindingNode()) 1941 return nullptr; 1942 1943 auto simpleBinding = static_cast<BindingNode*>(binding); 1944 const Identifier& ident = simpleBinding->boundProperty(); 1945 Local local = generator.local(ident); 1946 if (local.isCaptured()) 1947 return nullptr; 1948 return local.get(); 1949 } 1950 1951 return nullptr; 1952 } 1953 1954 void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName) 1955 { 1956 if (m_lexpr->isResolveNode()) { 1957 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); 1958 Local local = generator.local(ident); 1959 if (local.get()) 1960 generator.emitMove(local.get(), propertyName); 1961 else { 1954 1962 if (generator.isStrictMode()) 1955 1963 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); … … 1957 1965 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1958 1966 generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound); 1959 } else { 1960 expectedSubscript = generator.newTemporary(); 1961 propertyName = expectedSubscript.get(); 1962 generator.emitMove(local.get(), propertyName); 1963 generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), local.get()); 1964 optimizedForinAccess = true; 1965 } 1966 } else if (m_lexpr->isDotAccessorNode()) { 1967 } 1968 return; 1969 } 1970 if (m_lexpr->isDotAccessorNode()) { 1967 1971 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr); 1968 1972 const Identifier& ident = assignNode->identifier(); 1969 propertyName = generator.newTemporary();1970 RefPtr<RegisterID> protect = propertyName;1971 1973 RegisterID* base = generator.emitNode(assignNode->base()); 1972 1973 1974 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd()); 1974 1975 generator.emitPutById(base, ident, propertyName); 1975 } else if (m_lexpr->isBracketAccessorNode()) { 1976 return; 1977 } 1978 if (m_lexpr->isBracketAccessorNode()) { 1976 1979 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr); 1977 propertyName = generator.newTemporary();1978 RefPtr<RegisterID> protect = propertyName;1979 1980 RefPtr<RegisterID> base = generator.emitNode(assignNode->base()); 1980 1981 RegisterID* subscript = generator.emitNode(assignNode->subscript()); 1981 1982 1982 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd()); 1983 1983 generator.emitPutByVal(base.get(), subscript, propertyName); 1984 } else { 1985 ASSERT(m_lexpr->isDeconstructionNode()); 1984 return; 1985 } 1986 1987 if (m_lexpr->isDeconstructionNode()) { 1986 1988 DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr); 1987 1989 auto binding = assignNode->bindings(); 1988 if (binding->isBindingNode()) { 1989 auto simpleBinding = static_cast<BindingNode*>(binding); 1990 Identifier ident = simpleBinding->boundProperty(); 1991 Local local = generator.local(ident); 1992 propertyName = local.get(); 1993 // FIXME: Should I emit expression info here? 1994 if (!propertyName || local.isCaptured() || generator.isProfilingTypesWithHighFidelity()) 1995 goto genericBinding; 1996 expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName); 1997 generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName); 1998 optimizedForinAccess = true; 1999 goto completedSimpleBinding; 2000 } else { 2001 genericBinding: 2002 propertyName = generator.newTemporary(); 2003 RefPtr<RegisterID> protect(propertyName); 1990 if (!binding->isBindingNode()) { 2004 1991 assignNode->bindings()->bindValue(generator, propertyName); 2005 } 2006 completedSimpleBinding: 2007 ; 2008 } 2009 2010 generator.emitNode(dst, m_statement); 2011 2012 if (optimizedForinAccess) 2013 generator.popOptimisedForIn(); 2014 2015 generator.emitLabel(scope->continueTarget()); 2016 generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get()); 1992 return; 1993 } 1994 1995 auto simpleBinding = static_cast<BindingNode*>(binding); 1996 const Identifier& ident = simpleBinding->boundProperty(); 1997 Local local = generator.local(ident); 1998 if (!local.get() || local.isCaptured()) { 1999 assignNode->bindings()->bindValue(generator, propertyName); 2000 return; 2001 } 2002 generator.emitMove(local.get(), propertyName); 2003 return; 2004 } 2005 2006 RELEASE_ASSERT_NOT_REACHED(); 2007 } 2008 2009 void ForInNode::emitMultiLoopBytecode(BytecodeGenerator& generator, RegisterID* dst) 2010 { 2011 if (!m_lexpr->isAssignmentLocation()) { 2012 emitThrowReferenceError(generator, "Left side of for-in statement is not a reference."); 2013 return; 2014 } 2015 2016 RefPtr<Label> end = generator.newLabel(); 2017 2017 2018 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset()); 2018 generator.emitLabel(scope->breakTarget()); 2019 2020 RefPtr<RegisterID> base = generator.newTemporary(); 2021 RefPtr<RegisterID> length; 2022 RefPtr<RegisterID> structureEnumerator; 2023 generator.emitNode(base.get(), m_expr); 2024 RefPtr<RegisterID> local = this->tryGetBoundLocal(generator); 2025 2026 // Indexed property loop. 2027 { 2028 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop); 2029 RefPtr<Label> loopStart = generator.newLabel(); 2030 RefPtr<Label> loopEnd = generator.newLabel(); 2031 2032 length = generator.emitGetEnumerableLength(generator.newTemporary(), base.get()); 2033 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0)); 2034 RefPtr<RegisterID> propertyName = generator.newTemporary(); 2035 2036 generator.emitLabel(loopStart.get()); 2037 generator.emitLoopHint(); 2038 2039 RefPtr<RegisterID> result = generator.emitEqualityOp(op_less, generator.newTemporary(), i.get(), length.get()); 2040 generator.emitJumpIfFalse(result.get(), loopEnd.get()); 2041 generator.emitHasIndexedProperty(result.get(), base.get(), i.get()); 2042 generator.emitJumpIfFalse(result.get(), scope->continueTarget()); 2043 2044 generator.emitToIndexString(propertyName.get(), i.get()); 2045 this->emitLoopHeader(generator, propertyName.get()); 2046 2047 generator.pushIndexedForInScope(local.get(), i.get()); 2048 generator.emitNode(dst, m_statement); 2049 generator.popIndexedForInScope(local.get()); 2050 2051 generator.emitLabel(scope->continueTarget()); 2052 generator.emitInc(i.get()); 2053 generator.emitJump(loopStart.get()); 2054 2055 generator.emitLabel(scope->breakTarget()); 2056 generator.emitJump(end.get()); 2057 generator.emitLabel(loopEnd.get()); 2058 } 2059 2060 // Structure property loop. 2061 { 2062 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop); 2063 RefPtr<Label> loopStart = generator.newLabel(); 2064 RefPtr<Label> loopEnd = generator.newLabel(); 2065 2066 structureEnumerator = generator.emitGetStructurePropertyEnumerator(generator.newTemporary(), base.get(), length.get()); 2067 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0)); 2068 RefPtr<RegisterID> propertyName = generator.newTemporary(); 2069 generator.emitNextEnumeratorPropertyName(propertyName.get(), structureEnumerator.get(), i.get()); 2070 2071 generator.emitLabel(loopStart.get()); 2072 generator.emitLoopHint(); 2073 2074 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get()); 2075 generator.emitJumpIfTrue(result.get(), loopEnd.get()); 2076 generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), structureEnumerator.get()); 2077 generator.emitJumpIfFalse(result.get(), scope->continueTarget()); 2078 2079 this->emitLoopHeader(generator, propertyName.get()); 2080 2081 generator.pushStructureForInScope(local.get(), i.get(), propertyName.get(), structureEnumerator.get()); 2082 generator.emitNode(dst, m_statement); 2083 generator.popStructureForInScope(local.get()); 2084 2085 generator.emitLabel(scope->continueTarget()); 2086 generator.emitInc(i.get()); 2087 generator.emitNextEnumeratorPropertyName(propertyName.get(), structureEnumerator.get(), i.get()); 2088 generator.emitJump(loopStart.get()); 2089 2090 generator.emitLabel(scope->breakTarget()); 2091 generator.emitJump(end.get()); 2092 generator.emitLabel(loopEnd.get()); 2093 } 2094 2095 // Generic property loop. 2096 { 2097 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop); 2098 RefPtr<Label> loopStart = generator.newLabel(); 2099 RefPtr<Label> loopEnd = generator.newLabel(); 2100 2101 RefPtr<RegisterID> genericEnumerator = generator.emitGetGenericPropertyEnumerator(generator.newTemporary(), base.get(), length.get(), structureEnumerator.get()); 2102 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0)); 2103 RefPtr<RegisterID> propertyName = generator.newTemporary(); 2104 2105 generator.emitNextEnumeratorPropertyName(propertyName.get(), genericEnumerator.get(), i.get()); 2106 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get()); 2107 generator.emitJumpIfTrue(result.get(), loopEnd.get()); 2108 2109 generator.emitLabel(loopStart.get()); 2110 generator.emitLoopHint(); 2111 2112 this->emitLoopHeader(generator, propertyName.get()); 2113 2114 generator.emitNode(dst, m_statement); 2115 2116 generator.emitLabel(scope->continueTarget()); 2117 generator.emitInc(i.get()); 2118 generator.emitNextEnumeratorPropertyName(propertyName.get(), genericEnumerator.get(), i.get()); 2119 generator.emitUnaryOp(op_eq_null, result.get(), propertyName.get()); 2120 generator.emitJumpIfTrue(result.get(), loopEnd.get()); 2121 2122 generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get()); 2123 generator.emitJumpIfTrue(result.get(), loopStart.get()); 2124 generator.emitJump(scope->continueTarget()); 2125 2126 generator.emitLabel(scope->breakTarget()); 2127 generator.emitJump(end.get()); 2128 generator.emitLabel(loopEnd.get()); 2129 } 2130 2131 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset()); 2132 generator.emitLabel(end.get()); 2133 } 2134 2135 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 2136 { 2137 this->emitMultiLoopBytecode(generator, dst); 2019 2138 } 2020 2139 -
branches/ftlopt/Source/JavaScriptCore/debugger/DebuggerScope.h
r170680 r171605 95 95 JSScope* jsScope() const { return m_scope.get(); } 96 96 97 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Overrides VisitChildren | JSObject::StructureFlags;97 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | OverridesVisitChildren | JSObject::StructureFlags; 98 98 99 99 WriteBarrier<JSScope> m_scope; -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractHeap.h
r171106 r171605 54 54 macro(JSObject_butterfly) \ 55 55 macro(JSVariableObject_registers) \ 56 macro(JSPropertyNameEnumerator_cachedPropertyNames) \ 56 57 macro(NamedProperties) \ 57 58 macro(IndexedInt32Properties) \ -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r171495 r171605 1778 1778 } 1779 1779 1780 case In: 1780 case In: { 1781 1781 // FIXME: We can determine when the property definitely exists based on abstract 1782 1782 // value information. … … 1784 1784 forNode(node).setType(SpecBoolean); 1785 1785 break; 1786 1786 } 1787 1788 case GetEnumerableLength: { 1789 forNode(node).setType(SpecInt32); 1790 break; 1791 } 1792 case HasGenericProperty: { 1793 forNode(node).setType(SpecBoolean); 1794 break; 1795 } 1796 case HasStructureProperty: { 1797 forNode(node).setType(SpecBoolean); 1798 break; 1799 } 1800 case HasIndexedProperty: { 1801 ArrayMode mode = node->arrayMode(); 1802 switch (mode.type()) { 1803 case Array::Int32: 1804 case Array::Double: 1805 case Array::Contiguous: 1806 case Array::ArrayStorage: { 1807 break; 1808 } 1809 default: { 1810 clobberWorld(node->origin.semantic, clobberLimit); 1811 break; 1812 } 1813 } 1814 forNode(node).setType(SpecBoolean); 1815 break; 1816 } 1817 case GetDirectPname: { 1818 clobberWorld(node->origin.semantic, clobberLimit); 1819 forNode(node).makeHeapTop(); 1820 break; 1821 } 1822 case GetStructurePropertyEnumerator: { 1823 forNode(node).setType(SpecCell); 1824 break; 1825 } 1826 case GetGenericPropertyEnumerator: { 1827 forNode(node).setType(SpecCell); 1828 break; 1829 } 1830 case GetEnumeratorPname: { 1831 forNode(node).setType(SpecString | SpecOther); 1832 break; 1833 } 1834 case ToIndexString: { 1835 forNode(node).setType(SpecString); 1836 break; 1837 } 1838 1787 1839 case GetGlobalVar: 1788 1840 forNode(node).makeHeapTop(); -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r171389 r171605 3182 3182 } 3183 3183 3184 case op_get_enumerable_length: { 3185 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumerableLength, 3186 get(VirtualRegister(currentInstruction[2].u.operand)))); 3187 NEXT_OPCODE(op_get_enumerable_length); 3188 } 3189 3190 case op_has_generic_property: { 3191 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(HasGenericProperty, 3192 get(VirtualRegister(currentInstruction[2].u.operand)), 3193 get(VirtualRegister(currentInstruction[3].u.operand)))); 3194 NEXT_OPCODE(op_has_generic_property); 3195 } 3196 3197 case op_has_structure_property: { 3198 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(HasStructureProperty, 3199 get(VirtualRegister(currentInstruction[2].u.operand)), 3200 get(VirtualRegister(currentInstruction[3].u.operand)), 3201 get(VirtualRegister(currentInstruction[4].u.operand)))); 3202 NEXT_OPCODE(op_has_structure_property); 3203 } 3204 3205 case op_has_indexed_property: { 3206 Node* base = get(VirtualRegister(currentInstruction[2].u.operand)); 3207 ArrayMode arrayMode = getArrayModeConsideringSlowPath(currentInstruction[4].u.arrayProfile, Array::Read); 3208 Node* property = get(VirtualRegister(currentInstruction[3].u.operand)); 3209 Node* hasIterableProperty = addToGraph(HasIndexedProperty, OpInfo(arrayMode.asWord()), base, property); 3210 set(VirtualRegister(currentInstruction[1].u.operand), hasIterableProperty); 3211 NEXT_OPCODE(op_has_indexed_property); 3212 } 3213 3214 case op_get_direct_pname: { 3215 SpeculatedType prediction = getPredictionWithoutOSRExit(); 3216 3217 Node* base = get(VirtualRegister(currentInstruction[2].u.operand)); 3218 Node* property = get(VirtualRegister(currentInstruction[3].u.operand)); 3219 Node* index = get(VirtualRegister(currentInstruction[4].u.operand)); 3220 Node* enumerator = get(VirtualRegister(currentInstruction[5].u.operand)); 3221 3222 addVarArgChild(base); 3223 addVarArgChild(property); 3224 addVarArgChild(index); 3225 addVarArgChild(enumerator); 3226 set(VirtualRegister(currentInstruction[1].u.operand), 3227 addToGraph(Node::VarArg, GetDirectPname, OpInfo(0), OpInfo(prediction))); 3228 3229 NEXT_OPCODE(op_get_direct_pname); 3230 } 3231 3232 case op_get_structure_property_enumerator: { 3233 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetStructurePropertyEnumerator, 3234 get(VirtualRegister(currentInstruction[2].u.operand)), 3235 get(VirtualRegister(currentInstruction[3].u.operand)))); 3236 NEXT_OPCODE(op_get_structure_property_enumerator); 3237 } 3238 3239 case op_get_generic_property_enumerator: { 3240 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetGenericPropertyEnumerator, 3241 get(VirtualRegister(currentInstruction[2].u.operand)), 3242 get(VirtualRegister(currentInstruction[3].u.operand)), 3243 get(VirtualRegister(currentInstruction[4].u.operand)))); 3244 NEXT_OPCODE(op_get_generic_property_enumerator); 3245 } 3246 3247 case op_next_enumerator_pname: { 3248 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorPname, 3249 get(VirtualRegister(currentInstruction[2].u.operand)), 3250 get(VirtualRegister(currentInstruction[3].u.operand)))); 3251 NEXT_OPCODE(op_next_enumerator_pname); 3252 } 3253 3254 case op_to_index_string: { 3255 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(ToIndexString, 3256 get(VirtualRegister(currentInstruction[2].u.operand)))); 3257 NEXT_OPCODE(op_to_index_string); 3258 } 3259 3184 3260 default: 3185 3261 // Parse failed! This should not happen because the capabilities checker -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r170571 r171605 194 194 case op_in: 195 195 case op_get_from_scope: 196 case op_get_enumerable_length: 197 case op_has_generic_property: 198 case op_has_structure_property: 199 case op_has_indexed_property: 200 case op_get_direct_pname: 201 case op_get_structure_property_enumerator: 202 case op_get_generic_property_enumerator: 203 case op_next_enumerator_pname: 204 case op_to_index_string: 196 205 return CanCompileAndInline; 197 206 -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGClobberize.h
r171106 r171605 146 146 return; 147 147 148 case HasGenericProperty: 149 case HasStructureProperty: 150 case GetEnumerableLength: 151 case GetStructurePropertyEnumerator: 152 case GetGenericPropertyEnumerator: { 153 read(World); 154 write(SideState); 155 return; 156 } 157 158 case GetDirectPname: { 159 // This reads and writes world because it can end up calling a generic getByVal 160 // if the Structure changed, which could in turn end up calling a getter. 161 read(World); 162 write(World); 163 return; 164 } 165 166 case ToIndexString: 167 case GetEnumeratorPname: { 168 def(PureValue(node)); 169 return; 170 } 171 172 case HasIndexedProperty: { 173 read(JSObject_butterfly); 174 ArrayMode mode = node->arrayMode(); 175 switch (mode.type()) { 176 case Array::Int32: { 177 if (mode.isInBounds()) { 178 read(Butterfly_publicLength); 179 read(IndexedInt32Properties); 180 def(HeapLocation(HasIndexedPropertyLoc, IndexedInt32Properties, node->child1(), node->child2()), node); 181 return; 182 } 183 read(World); 184 return; 185 } 186 187 case Array::Double: { 188 if (mode.isInBounds()) { 189 read(Butterfly_publicLength); 190 read(IndexedDoubleProperties); 191 def(HeapLocation(HasIndexedPropertyLoc, IndexedDoubleProperties, node->child1(), node->child2()), node); 192 return; 193 } 194 read(World); 195 return; 196 } 197 198 case Array::Contiguous: { 199 if (mode.isInBounds()) { 200 read(Butterfly_publicLength); 201 read(IndexedContiguousProperties); 202 def(HeapLocation(HasIndexedPropertyLoc, IndexedContiguousProperties, node->child1(), node->child2()), node); 203 return; 204 } 205 read(World); 206 return; 207 } 208 209 case Array::ArrayStorage: { 210 if (mode.isInBounds()) { 211 read(Butterfly_vectorLength); 212 read(IndexedArrayStorageProperties); 213 return; 214 } 215 read(World); 216 return; 217 } 218 219 default: { 220 read(World); 221 write(World); 222 return; 223 } 224 } 225 RELEASE_ASSERT_NOT_REACHED(); 226 return; 227 } 228 148 229 case ArithAdd: 149 230 case ArithSub: -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r170092 r171605 188 188 case GetGetterSetterByOffset: 189 189 case PutByOffset: 190 case GetEnumerableLength: 191 case HasGenericProperty: 192 case HasStructureProperty: 193 case HasIndexedProperty: 194 case GetDirectPname: 190 195 return false; 191 196 … … 210 215 case NewTypedArray: 211 216 case ThrowReferenceError: 217 case GetStructurePropertyEnumerator: 218 case GetGenericPropertyEnumerator: 219 case GetEnumeratorPname: 220 case ToIndexString: 212 221 return true; 213 222 -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r171389 r171605 1035 1035 } 1036 1036 break; 1037 1038 case GetEnumerableLength: { 1039 fixEdge<CellUse>(node->child1()); 1040 break; 1041 } 1042 case HasGenericProperty: { 1043 fixEdge<StringUse>(node->child2()); 1044 break; 1045 } 1046 case HasStructureProperty: { 1047 fixEdge<StringUse>(node->child2()); 1048 fixEdge<KnownCellUse>(node->child3()); 1049 break; 1050 } 1051 case HasIndexedProperty: { 1052 node->setArrayMode( 1053 node->arrayMode().refine( 1054 m_graph, node, 1055 node->child1()->prediction(), 1056 node->child2()->prediction(), 1057 SpecNone, node->flags())); 1058 1059 blessArrayOperation(node->child1(), node->child2(), node->child3()); 1060 fixEdge<CellUse>(node->child1()); 1061 fixEdge<KnownInt32Use>(node->child2()); 1062 break; 1063 } 1064 case GetDirectPname: { 1065 Edge& base = m_graph.varArgChild(node, 0); 1066 Edge& property = m_graph.varArgChild(node, 1); 1067 Edge& index = m_graph.varArgChild(node, 2); 1068 Edge& enumerator = m_graph.varArgChild(node, 3); 1069 fixEdge<CellUse>(base); 1070 fixEdge<KnownCellUse>(property); 1071 fixEdge<KnownInt32Use>(index); 1072 fixEdge<KnownCellUse>(enumerator); 1073 break; 1074 } 1075 case GetStructurePropertyEnumerator: { 1076 fixEdge<CellUse>(node->child1()); 1077 fixEdge<KnownInt32Use>(node->child2()); 1078 break; 1079 } 1080 case GetGenericPropertyEnumerator: { 1081 fixEdge<CellUse>(node->child1()); 1082 fixEdge<KnownInt32Use>(node->child2()); 1083 fixEdge<KnownCellUse>(node->child3()); 1084 break; 1085 } 1086 case GetEnumeratorPname: { 1087 fixEdge<KnownCellUse>(node->child1()); 1088 fixEdge<KnownInt32Use>(node->child2()); 1089 break; 1090 } 1091 case ToIndexString: { 1092 fixEdge<KnownInt32Use>(node->child1()); 1093 break; 1094 } 1037 1095 1038 1096 #if !ASSERT_DISABLED -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp
r171106 r171605 109 109 return; 110 110 111 case HasIndexedPropertyLoc: 112 out.print("HasIndexedPorpertyLoc"); 113 return; 114 111 115 case IndexedPropertyLoc: 112 116 out.print("IndexedPorpertyLoc"); -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGHeapLocation.h
r171106 r171605 45 45 GetterLoc, 46 46 GlobalVariableLoc, 47 HasIndexedPropertyLoc, 47 48 IndexedPropertyLoc, 48 49 IndexedPropertyStorageLoc, -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGNode.h
r171152 r171605 1002 1002 { 1003 1003 switch (op()) { 1004 case GetDirectPname: 1004 1005 case GetById: 1005 1006 case GetByIdFlush: … … 1262 1263 case ArrayPush: 1263 1264 case ArrayPop: 1265 case HasIndexedProperty: 1264 1266 return true; 1265 1267 default: -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGNodeType.h
r171495 r171605 289 289 macro(StoreBarrier, NodeMustGenerate) \ 290 290 macro(StoreBarrierWithNullCheck, NodeMustGenerate) \ 291 \ 292 /* For-in enumeration opcodes */\ 293 macro(GetEnumerableLength, NodeMustGenerate | NodeResultJS) \ 294 macro(HasIndexedProperty, NodeResultBoolean) \ 295 macro(HasStructureProperty, NodeResultBoolean) \ 296 macro(HasGenericProperty, NodeResultBoolean) \ 297 macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \ 298 macro(GetStructurePropertyEnumerator, NodeMustGenerate | NodeResultJS) \ 299 macro(GetGenericPropertyEnumerator, NodeMustGenerate | NodeResultJS) \ 300 macro(GetEnumeratorPname, NodeMustGenerate | NodeResultJS) \ 301 macro(ToIndexString, NodeResultJS) 291 302 292 303 // This enum generates a monotonically increasing id for all Node types, -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r170092 r171605 181 181 case GetByOffset: 182 182 case MultiGetByOffset: 183 case GetDirectPname: 183 184 case Call: 184 185 case Construct: … … 550 551 changed |= setPrediction(SpecBoolean); 551 552 break; 553 554 case GetEnumerableLength: { 555 changed |= setPrediction(SpecInt32); 556 break; 557 } 558 case HasGenericProperty: { 559 changed |= setPrediction(SpecBoolean); 560 break; 561 } 562 case HasStructureProperty: { 563 changed |= setPrediction(SpecBoolean); 564 break; 565 } 566 case HasIndexedProperty: { 567 changed |= setPrediction(SpecBoolean); 568 break; 569 } 570 case GetStructurePropertyEnumerator: { 571 changed |= setPrediction(SpecCell); 572 break; 573 } 574 case GetGenericPropertyEnumerator: { 575 changed |= setPrediction(SpecCell); 576 break; 577 } 578 case GetEnumeratorPname: { 579 changed |= setPrediction(SpecCell | SpecOther); 580 break; 581 } 582 case ToIndexString: { 583 changed |= setPrediction(SpecString); 584 break; 585 } 552 586 553 587 #ifndef NDEBUG -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r171389 r171605 256 256 case GetGetter: 257 257 case GetSetter: 258 case GetEnumerableLength: 259 case HasGenericProperty: 260 case HasStructureProperty: 261 case HasIndexedProperty: 262 case GetDirectPname: 263 case GetStructurePropertyEnumerator: 264 case GetGenericPropertyEnumerator: 265 case GetEnumeratorPname: 266 case ToIndexString: 258 267 return true; 259 268 -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r171389 r171605 1035 1035 return appendCallWithExceptionCheckSetResult(operation, result); 1036 1036 } 1037 JITCompiler::Call callOperation(C_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) 1038 { 1039 m_jit.setupArgumentsWithExecState(arg1, arg2); 1040 return appendCallWithExceptionCheckSetResult(operation, result); 1041 } 1042 JITCompiler::Call callOperation(C_JITOperation_ECZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) 1043 { 1044 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); 1045 return appendCallWithExceptionCheckSetResult(operation, result); 1046 } 1037 1047 JITCompiler::Call callOperation(C_JITOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell) 1038 1048 { … … 1132 1142 m_jit.setupArgumentsExecState(); 1133 1143 return appendCallWithCallFrameRollbackOnExceptionSetResult(operation, result); 1144 } 1145 JITCompiler::Call callOperation(Z_JITOperation_EC operation, GPRReg result, GPRReg arg1) 1146 { 1147 m_jit.setupArgumentsWithExecState(arg1); 1148 return appendCallWithExceptionCheckSetResult(operation, result); 1134 1149 } 1135 1150 … … 1249 1264 return appendCallWithExceptionCheckSetResult(operation, result); 1250 1265 } 1266 JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) 1267 { 1268 m_jit.setupArgumentsWithExecState(arg1, arg2); 1269 return appendCallWithExceptionCheckSetResult(operation, result); 1270 } 1251 1271 JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const StringImpl* uid) 1252 1272 { … … 1260 1280 } 1261 1281 JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2) 1282 { 1283 m_jit.setupArgumentsWithExecState(arg1, arg2); 1284 return appendCallWithExceptionCheckSetResult(operation, result); 1285 } 1286 JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg result, GPRReg arg1, GPRReg arg2) 1287 { 1288 m_jit.setupArgumentsWithExecState(arg1, arg2); 1289 return appendCallWithExceptionCheckSetResult(operation, result); 1290 } 1291 JITCompiler::Call callOperation(J_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) 1262 1292 { 1263 1293 m_jit.setupArgumentsWithExecState(arg1, arg2); … … 1310 1340 { 1311 1341 m_jit.setupArgumentsWithExecState(arg1); 1342 return appendCallWithExceptionCheckSetResult(operation, result); 1343 } 1344 JITCompiler::Call callOperation(C_JITOperation_EJJC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) 1345 { 1346 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); 1347 return appendCallWithExceptionCheckSetResult(operation, result); 1348 } 1349 JITCompiler::Call callOperation(C_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) 1350 { 1351 m_jit.setupArgumentsWithExecState(arg1, arg2); 1352 return appendCallWithExceptionCheckSetResult(operation, result); 1353 } 1354 JITCompiler::Call callOperation(C_JITOperation_EJZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3) 1355 { 1356 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); 1312 1357 return appendCallWithExceptionCheckSetResult(operation, result); 1313 1358 } … … 1485 1530 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1486 1531 } 1532 JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultPayload, GPRReg resultTag, GPRReg arg1) 1533 { 1534 m_jit.setupArgumentsWithExecState(arg1); 1535 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1536 } 1537 JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2) 1538 { 1539 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2); 1540 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1541 } 1487 1542 JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2) 1488 1543 { … … 1514 1569 { 1515 1570 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell)); 1571 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1572 } 1573 JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2) 1574 { 1575 m_jit.setupArgumentsWithExecState(arg1, arg2); 1516 1576 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1517 1577 } -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r171495 r171605 38 38 #include "GetterSetter.h" 39 39 #include "JSActivation.h" 40 #include "JSPropertyNameEnumerator.h" 40 41 #include "ObjectPrototype.h" 41 42 #include "JSCInlines.h" … … 4549 4550 } 4550 4551 4552 case GetEnumerableLength: { 4553 SpeculateCellOperand base(this, node->child1()); 4554 GPRResult result(this); 4555 GPRReg resultGPR = result.gpr(); 4556 4557 flushRegisters(); 4558 callOperation(operationGetEnumerableLength, resultGPR, base.gpr()); 4559 int32Result(resultGPR, node); 4560 break; 4561 } 4562 case HasGenericProperty: { 4563 JSValueOperand base(this, node->child1()); 4564 SpeculateCellOperand property(this, node->child2()); 4565 GPRResult resultPayload(this); 4566 GPRResult2 resultTag(this); 4567 GPRReg basePayloadGPR = base.payloadGPR(); 4568 GPRReg baseTagGPR = base.tagGPR(); 4569 GPRReg resultPayloadGPR = resultPayload.gpr(); 4570 GPRReg resultTagGPR = resultTag.gpr(); 4571 4572 flushRegisters(); 4573 callOperation(operationHasGenericProperty, resultTagGPR, resultPayloadGPR, baseTagGPR, basePayloadGPR, property.gpr()); 4574 booleanResult(resultPayloadGPR, node); 4575 break; 4576 } 4577 case HasStructureProperty: { 4578 JSValueOperand base(this, node->child1()); 4579 SpeculateCellOperand property(this, node->child2()); 4580 SpeculateCellOperand enumerator(this, node->child3()); 4581 GPRTemporary scratch(this); 4582 GPRResult resultPayload(this); 4583 GPRResult2 resultTag(this); 4584 4585 GPRReg baseTagGPR = base.tagGPR(); 4586 GPRReg basePayloadGPR = base.payloadGPR(); 4587 GPRReg propertyGPR = property.gpr(); 4588 GPRReg scratchGPR = scratch.gpr(); 4589 GPRReg resultPayloadGPR = resultPayload.gpr(); 4590 GPRReg resultTagGPR = resultTag.gpr(); 4591 4592 m_jit.load32(MacroAssembler::Address(basePayloadGPR, JSCell::structureIDOffset()), scratchGPR); 4593 MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual, 4594 scratchGPR, 4595 MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::cachedStructureIDOffset())); 4596 4597 moveTrueTo(resultPayloadGPR); 4598 MacroAssembler::Jump done = m_jit.jump(); 4599 4600 done.link(&m_jit); 4601 4602 addSlowPathGenerator(slowPathCall(wrongStructure, this, operationHasGenericProperty, resultTagGPR, resultPayloadGPR, baseTagGPR, basePayloadGPR, propertyGPR)); 4603 booleanResult(resultPayloadGPR, node); 4604 break; 4605 } 4606 case HasIndexedProperty: { 4607 SpeculateCellOperand base(this, node->child1()); 4608 SpeculateInt32Operand index(this, node->child2()); 4609 GPRResult resultPayload(this); 4610 GPRResult2 resultTag(this); 4611 4612 GPRReg baseGPR = base.gpr(); 4613 GPRReg indexGPR = index.gpr(); 4614 GPRReg resultPayloadGPR = resultPayload.gpr(); 4615 GPRReg resultTagGPR = resultTag.gpr(); 4616 4617 MacroAssembler::JumpList slowCases; 4618 ArrayMode mode = node->arrayMode(); 4619 switch (mode.type()) { 4620 case Array::Int32: 4621 case Array::Contiguous: { 4622 ASSERT(!!node->child3()); 4623 StorageOperand storage(this, node->child3()); 4624 GPRTemporary scratch(this); 4625 4626 GPRReg storageGPR = storage.gpr(); 4627 GPRReg scratchGPR = scratch.gpr(); 4628 4629 slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()))); 4630 m_jit.load32(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), scratchGPR); 4631 slowCases.append(m_jit.branch32(MacroAssembler::Equal, scratchGPR, TrustedImm32(JSValue::EmptyValueTag))); 4632 break; 4633 } 4634 case Array::Double: { 4635 ASSERT(!!node->child3()); 4636 StorageOperand storage(this, node->child3()); 4637 FPRTemporary scratch(this); 4638 FPRReg scratchFPR = scratch.fpr(); 4639 GPRReg storageGPR = storage.gpr(); 4640 4641 slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()))); 4642 m_jit.loadDouble(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchFPR); 4643 slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, scratchFPR, scratchFPR)); 4644 break; 4645 } 4646 case Array::ArrayStorage: { 4647 ASSERT(!!node->child3()); 4648 StorageOperand storage(this, node->child3()); 4649 GPRTemporary scratch(this); 4650 4651 GPRReg storageGPR = storage.gpr(); 4652 GPRReg scratchGPR = scratch.gpr(); 4653 4654 slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()))); 4655 m_jit.load32(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), scratchGPR); 4656 slowCases.append(m_jit.branch32(MacroAssembler::Equal, scratchGPR, TrustedImm32(JSValue::EmptyValueTag))); 4657 break; 4658 } 4659 default: { 4660 slowCases.append(m_jit.jump()); 4661 break; 4662 } 4663 } 4664 4665 moveTrueTo(resultPayloadGPR); 4666 MacroAssembler::Jump done = m_jit.jump(); 4667 4668 addSlowPathGenerator(slowPathCall(slowCases, this, operationHasIndexedProperty, resultTagGPR, resultPayloadGPR, baseGPR, indexGPR)); 4669 4670 done.link(&m_jit); 4671 booleanResult(resultPayloadGPR, node); 4672 break; 4673 } 4674 case GetDirectPname: { 4675 Edge& baseEdge = m_jit.graph().varArgChild(node, 0); 4676 Edge& propertyEdge = m_jit.graph().varArgChild(node, 1); 4677 Edge& indexEdge = m_jit.graph().varArgChild(node, 2); 4678 Edge& enumeratorEdge = m_jit.graph().varArgChild(node, 3); 4679 4680 SpeculateCellOperand base(this, baseEdge); 4681 SpeculateCellOperand property(this, propertyEdge); 4682 SpeculateInt32Operand index(this, indexEdge); 4683 SpeculateCellOperand enumerator(this, enumeratorEdge); 4684 GPRResult resultPayload(this); 4685 GPRResult2 resultTag(this); 4686 GPRTemporary scratch(this); 4687 4688 GPRReg baseGPR = base.gpr(); 4689 GPRReg propertyGPR = property.gpr(); 4690 GPRReg indexGPR = index.gpr(); 4691 GPRReg enumeratorGPR = enumerator.gpr(); 4692 GPRReg resultTagGPR = resultTag.gpr(); 4693 GPRReg resultPayloadGPR = resultPayload.gpr(); 4694 GPRReg scratchGPR = scratch.gpr(); 4695 4696 // Check the structure 4697 m_jit.load32(MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), scratchGPR); 4698 MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual, 4699 scratchGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset())); 4700 4701 // Compute the offset 4702 // If index is less than the enumerator's cached inline storage, then it's an inline access 4703 MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual, 4704 indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset())); 4705 4706 m_jit.move(indexGPR, scratchGPR); 4707 m_jit.signExtend32ToPtr(scratchGPR, scratchGPR); 4708 m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR); 4709 m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR); 4710 4711 MacroAssembler::Jump done = m_jit.jump(); 4712 4713 // Otherwise it's out of line 4714 outOfLineAccess.link(&m_jit); 4715 m_jit.move(indexGPR, scratchGPR); 4716 m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratchGPR); 4717 m_jit.neg32(scratchGPR); 4718 m_jit.signExtend32ToPtr(scratchGPR, scratchGPR); 4719 // We use resultPayloadGPR as a temporary here. We have to make sure clobber it after getting the 4720 // value out of indexGPR and enumeratorGPR because resultPayloadGPR could reuse either of those registers. 4721 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), resultPayloadGPR); 4722 int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue); 4723 m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR); 4724 m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR); 4725 4726 done.link(&m_jit); 4727 4728 m_jit.move(MacroAssembler::TrustedImm32(JSValue::CellTag), scratchGPR); 4729 addSlowPathGenerator(slowPathCall(wrongStructure, this, operationGetByValCell, resultTagGPR, resultPayloadGPR, baseGPR, scratchGPR, propertyGPR)); 4730 4731 jsValueResult(resultTagGPR, resultPayloadGPR, node); 4732 break; 4733 } 4734 case GetStructurePropertyEnumerator: { 4735 SpeculateCellOperand base(this, node->child1()); 4736 SpeculateInt32Operand length(this, node->child2()); 4737 GPRResult result(this); 4738 GPRReg resultGPR = result.gpr(); 4739 4740 flushRegisters(); 4741 callOperation(operationGetStructurePropertyEnumerator, resultGPR, base.gpr(), length.gpr()); 4742 cellResult(resultGPR, node); 4743 break; 4744 } 4745 case GetGenericPropertyEnumerator: { 4746 SpeculateCellOperand base(this, node->child1()); 4747 SpeculateInt32Operand length(this, node->child2()); 4748 SpeculateCellOperand enumerator(this, node->child3()); 4749 GPRResult result(this); 4750 GPRReg resultGPR = result.gpr(); 4751 4752 flushRegisters(); 4753 callOperation(operationGetGenericPropertyEnumerator, resultGPR, base.gpr(), length.gpr(), enumerator.gpr()); 4754 cellResult(resultGPR, node); 4755 break; 4756 } 4757 case GetEnumeratorPname: { 4758 SpeculateCellOperand enumerator(this, node->child1()); 4759 SpeculateInt32Operand index(this, node->child2()); 4760 GPRTemporary scratch(this); 4761 GPRResult resultPayload(this); 4762 GPRResult2 resultTag(this); 4763 4764 GPRReg enumeratorGPR = enumerator.gpr(); 4765 GPRReg indexGPR = index.gpr(); 4766 GPRReg scratchGPR = scratch.gpr(); 4767 GPRReg resultTagGPR = resultTag.gpr(); 4768 GPRReg resultPayloadGPR = resultPayload.gpr(); 4769 4770 MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, 4771 indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset())); 4772 4773 m_jit.move(MacroAssembler::TrustedImm32(JSValue::NullTag), resultTagGPR); 4774 m_jit.move(MacroAssembler::TrustedImm32(0), resultPayloadGPR); 4775 4776 MacroAssembler::Jump done = m_jit.jump(); 4777 inBounds.link(&m_jit); 4778 4779 m_jit.loadPtr(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), scratchGPR); 4780 m_jit.loadPtr(MacroAssembler::BaseIndex(scratchGPR, indexGPR, MacroAssembler::ScalePtr), resultPayloadGPR); 4781 m_jit.move(MacroAssembler::TrustedImm32(JSValue::CellTag), resultTagGPR); 4782 4783 done.link(&m_jit); 4784 jsValueResult(resultTagGPR, resultPayloadGPR, node); 4785 break; 4786 } 4787 case ToIndexString: { 4788 SpeculateInt32Operand index(this, node->child1()); 4789 GPRResult result(this); 4790 GPRReg resultGPR = result.gpr(); 4791 4792 flushRegisters(); 4793 callOperation(operationToIndexString, resultGPR, index.gpr()); 4794 cellResult(resultGPR, node); 4795 break; 4796 } 4797 4551 4798 case ForceOSRExit: { 4552 4799 terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0); -
branches/ftlopt/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r171495 r171605 38 38 #include "GetterSetter.h" 39 39 #include "JSCInlines.h" 40 #include "JSPropertyNameEnumerator.h" 40 41 #include "ObjectPrototype.h" 41 42 #include "SpillRegistersMode.h" … … 4584 4585 } 4585 4586 4587 case GetEnumerableLength: { 4588 SpeculateCellOperand base(this, node->child1()); 4589 GPRResult result(this); 4590 GPRReg resultGPR = result.gpr(); 4591 4592 flushRegisters(); 4593 callOperation(operationGetEnumerableLength, resultGPR, base.gpr()); 4594 int32Result(resultGPR, node); 4595 break; 4596 } 4597 case HasGenericProperty: { 4598 JSValueOperand base(this, node->child1()); 4599 SpeculateCellOperand property(this, node->child2()); 4600 GPRResult result(this); 4601 GPRReg resultGPR = result.gpr(); 4602 4603 flushRegisters(); 4604 callOperation(operationHasGenericProperty, resultGPR, base.gpr(), property.gpr()); 4605 jsValueResult(resultGPR, node, DataFormatJSBoolean); 4606 break; 4607 } 4608 case HasStructureProperty: { 4609 JSValueOperand base(this, node->child1()); 4610 SpeculateCellOperand property(this, node->child2()); 4611 SpeculateCellOperand enumerator(this, node->child3()); 4612 GPRTemporary scratch(this); 4613 GPRResult result(this); 4614 4615 GPRReg baseGPR = base.gpr(); 4616 GPRReg propertyGPR = property.gpr(); 4617 GPRReg scratchGPR = scratch.gpr(); 4618 GPRReg resultGPR = result.gpr(); 4619 4620 m_jit.load32(MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), scratchGPR); 4621 MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual, 4622 scratchGPR, 4623 MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::cachedStructureIDOffset())); 4624 4625 moveTrueTo(resultGPR); 4626 MacroAssembler::Jump done = m_jit.jump(); 4627 4628 done.link(&m_jit); 4629 4630 addSlowPathGenerator(slowPathCall(wrongStructure, this, operationHasGenericProperty, resultGPR, baseGPR, propertyGPR)); 4631 jsValueResult(resultGPR, node, DataFormatJSBoolean); 4632 break; 4633 } 4634 case HasIndexedProperty: { 4635 SpeculateCellOperand base(this, node->child1()); 4636 SpeculateInt32Operand index(this, node->child2()); 4637 GPRResult result(this); 4638 4639 GPRReg baseGPR = base.gpr(); 4640 GPRReg indexGPR = index.gpr(); 4641 GPRReg resultGPR = result.gpr(); 4642 4643 MacroAssembler::JumpList slowCases; 4644 ArrayMode mode = node->arrayMode(); 4645 switch (mode.type()) { 4646 case Array::Int32: 4647 case Array::Contiguous: { 4648 ASSERT(!!node->child3()); 4649 StorageOperand storage(this, node->child3()); 4650 GPRTemporary scratch(this); 4651 4652 GPRReg storageGPR = storage.gpr(); 4653 GPRReg scratchGPR = scratch.gpr(); 4654 4655 MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); 4656 if (mode.isInBounds()) 4657 speculationCheck(OutOfBounds, JSValueRegs(), 0, outOfBounds); 4658 else 4659 slowCases.append(outOfBounds); 4660 4661 m_jit.load64(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchGPR); 4662 slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, scratchGPR)); 4663 moveTrueTo(resultGPR); 4664 break; 4665 } 4666 case Array::Double: { 4667 ASSERT(!!node->child3()); 4668 StorageOperand storage(this, node->child3()); 4669 FPRTemporary scratch(this); 4670 FPRReg scratchFPR = scratch.fpr(); 4671 GPRReg storageGPR = storage.gpr(); 4672 4673 MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); 4674 if (mode.isInBounds()) 4675 speculationCheck(OutOfBounds, JSValueRegs(), 0, outOfBounds); 4676 else 4677 slowCases.append(outOfBounds); 4678 4679 m_jit.loadDouble(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchFPR); 4680 slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, scratchFPR, scratchFPR)); 4681 break; 4682 } 4683 case Array::ArrayStorage: { 4684 ASSERT(!!node->child3()); 4685 StorageOperand storage(this, node->child3()); 4686 GPRTemporary scratch(this); 4687 4688 GPRReg storageGPR = storage.gpr(); 4689 GPRReg scratchGPR = scratch.gpr(); 4690 4691 MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())); 4692 if (mode.isInBounds()) 4693 speculationCheck(OutOfBounds, JSValueRegs(), 0, outOfBounds); 4694 else 4695 slowCases.append(outOfBounds); 4696 4697 m_jit.load64(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), scratchGPR); 4698 slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, scratchGPR)); 4699 moveTrueTo(resultGPR); 4700 break; 4701 } 4702 default: { 4703 slowCases.append(m_jit.jump()); 4704 break; 4705 } 4706 } 4707 4708 addSlowPathGenerator(slowPathCall(slowCases, this, operationHasIndexedProperty, resultGPR, baseGPR, indexGPR)); 4709 4710 jsValueResult(resultGPR, node, DataFormatJSBoolean); 4711 break; 4712 } 4713 case GetDirectPname: { 4714 Edge& baseEdge = m_jit.graph().varArgChild(node, 0); 4715 Edge& propertyEdge = m_jit.graph().varArgChild(node, 1); 4716 Edge& indexEdge = m_jit.graph().varArgChild(node, 2); 4717 Edge& enumeratorEdge = m_jit.graph().varArgChild(node, 3); 4718 4719 SpeculateCellOperand base(this, baseEdge); 4720 SpeculateCellOperand property(this, propertyEdge); 4721 SpeculateInt32Operand index(this, indexEdge); 4722 SpeculateCellOperand enumerator(this, enumeratorEdge); 4723 GPRResult result(this); 4724 GPRTemporary scratch1(this); 4725 GPRTemporary scratch2(this); 4726 4727 GPRReg baseGPR = base.gpr(); 4728 GPRReg propertyGPR = property.gpr(); 4729 GPRReg indexGPR = index.gpr(); 4730 GPRReg enumeratorGPR = enumerator.gpr(); 4731 GPRReg resultGPR = result.gpr(); 4732 GPRReg scratch1GPR = scratch1.gpr(); 4733 GPRReg scratch2GPR = scratch2.gpr(); 4734 4735 // Check the structure 4736 m_jit.load32(MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()), scratch1GPR); 4737 MacroAssembler::Jump wrongStructure = m_jit.branch32(MacroAssembler::NotEqual, 4738 scratch1GPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedStructureIDOffset())); 4739 4740 // Compute the offset 4741 // If index is less than the enumerator's cached inline storage, then it's an inline access 4742 MacroAssembler::Jump outOfLineAccess = m_jit.branch32(MacroAssembler::AboveOrEqual, 4743 indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset())); 4744 4745 m_jit.load64(MacroAssembler::BaseIndex(baseGPR, indexGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage()), resultGPR); 4746 4747 MacroAssembler::Jump done = m_jit.jump(); 4748 4749 // Otherwise it's out of line 4750 outOfLineAccess.link(&m_jit); 4751 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratch2GPR); 4752 m_jit.move(indexGPR, scratch1GPR); 4753 m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratch1GPR); 4754 m_jit.neg32(scratch1GPR); 4755 m_jit.signExtend32ToPtr(scratch1GPR, scratch1GPR); 4756 int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue); 4757 m_jit.load64(MacroAssembler::BaseIndex(scratch2GPR, scratch1GPR, MacroAssembler::TimesEight, offsetOfFirstProperty), resultGPR); 4758 4759 done.link(&m_jit); 4760 4761 addSlowPathGenerator(slowPathCall(wrongStructure, this, operationGetByVal, resultGPR, baseGPR, propertyGPR)); 4762 4763 jsValueResult(resultGPR, node); 4764 break; 4765 } 4766 case GetStructurePropertyEnumerator: { 4767 SpeculateCellOperand base(this, node->child1()); 4768 SpeculateInt32Operand length(this, node->child2()); 4769 GPRResult result(this); 4770 GPRReg resultGPR = result.gpr(); 4771 4772 flushRegisters(); 4773 callOperation(operationGetStructurePropertyEnumerator, resultGPR, base.gpr(), length.gpr()); 4774 cellResult(resultGPR, node); 4775 break; 4776 } 4777 case GetGenericPropertyEnumerator: { 4778 SpeculateCellOperand base(this, node->child1()); 4779 SpeculateInt32Operand length(this, node->child2()); 4780 SpeculateCellOperand enumerator(this, node->child3()); 4781 GPRResult result(this); 4782 GPRReg resultGPR = result.gpr(); 4783 4784 flushRegisters(); 4785 callOperation(operationGetGenericPropertyEnumerator, resultGPR, base.gpr(), length.gpr(), enumerator.gpr()); 4786 cellResult(resultGPR, node); 4787 break; 4788 } 4789 case GetEnumeratorPname: { 4790 SpeculateCellOperand enumerator(this, node->child1()); 4791 SpeculateInt32Operand index(this, node->child2()); 4792 GPRTemporary scratch1(this); 4793 GPRTemporary scratch2(this); 4794 GPRResult result(this); 4795 4796 GPRReg enumeratorGPR = enumerator.gpr(); 4797 GPRReg indexGPR = index.gpr(); 4798 GPRReg scratch1GPR = scratch1.gpr(); 4799 GPRReg scratch2GPR = scratch2.gpr(); 4800 GPRReg resultGPR = result.gpr(); 4801 4802 MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, 4803 indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset())); 4804 4805 m_jit.move(MacroAssembler::TrustedImm32(ValueNull), resultGPR); 4806 4807 MacroAssembler::Jump done = m_jit.jump(); 4808 inBounds.link(&m_jit); 4809 4810 m_jit.loadPtr(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), scratch1GPR); 4811 m_jit.move(indexGPR, scratch2GPR); 4812 m_jit.signExtend32ToPtr(scratch2GPR, scratch2GPR); 4813 m_jit.load64(MacroAssembler::BaseIndex(scratch1GPR, scratch2GPR, MacroAssembler::TimesEight), resultGPR); 4814 4815 done.link(&m_jit); 4816 jsValueResult(resultGPR, node); 4817 break; 4818 } 4819 case ToIndexString: { 4820 SpeculateInt32Operand index(this, node->child1()); 4821 GPRResult result(this); 4822 GPRReg resultGPR = result.gpr(); 4823 4824 flushRegisters(); 4825 callOperation(operationToIndexString, resultGPR, index.gpr()); 4826 cellResult(resultGPR, node); 4827 break; 4828 } 4829 4586 4830 #if ENABLE(FTL_JIT) 4587 4831 case CheckTierUpInLoop: { -
branches/ftlopt/Source/JavaScriptCore/jit/JIT.cpp
r169143 r171605 304 304 DEFINE_OP(op_get_from_scope) 305 305 DEFINE_OP(op_put_to_scope) 306 307 DEFINE_OP(op_get_enumerable_length) 308 DEFINE_OP(op_has_generic_property) 309 DEFINE_OP(op_has_structure_property) 310 DEFINE_OP(op_has_indexed_property) 311 DEFINE_OP(op_get_direct_pname) 312 DEFINE_OP(op_get_structure_property_enumerator) 313 DEFINE_OP(op_get_generic_property_enumerator) 314 DEFINE_OP(op_next_enumerator_pname) 315 DEFINE_OP(op_to_index_string) 306 316 default: 307 317 RELEASE_ASSERT_NOT_REACHED(); … … 421 431 DEFINE_SLOWCASE_OP(op_to_number) 422 432 DEFINE_SLOWCASE_OP(op_to_primitive) 433 DEFINE_SLOWCASE_OP(op_has_indexed_property) 434 DEFINE_SLOWCASE_OP(op_has_structure_property) 435 DEFINE_SLOWCASE_OP(op_get_direct_pname) 423 436 424 437 DEFINE_SLOWCASE_OP(op_resolve_scope) -
branches/ftlopt/Source/JavaScriptCore/jit/JIT.h
r171389 r171605 221 221 } 222 222 223 static void compileHasIndexedProperty(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) 224 { 225 JIT jit(vm, codeBlock); 226 jit.m_bytecodeOffset = byValInfo->bytecodeIndex; 227 jit.privateCompileHasIndexedProperty(byValInfo, returnAddress, arrayMode); 228 } 229 223 230 static CodeRef compileCTINativeCall(VM* vm, NativeFunction func) 224 231 { … … 247 254 void privateCompileGetByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode); 248 255 void privateCompilePutByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode); 256 257 void privateCompileHasIndexedProperty(ByValInfo*, ReturnAddressPtr, JITArrayMode); 249 258 250 259 Label privateCompileCTINativeCall(VM*, bool isConstruct = false); … … 328 337 // Structure is already profiled. Returns the slow cases. Fall-through 329 338 // case contains result in regT0, and it is not yet profiled. 339 JumpList emitInt32Load(Instruction* instruction, PatchableJump& badType) { return emitContiguousLoad(instruction, badType, Int32Shape); } 340 JumpList emitDoubleLoad(Instruction*, PatchableJump& badType); 341 JumpList emitContiguousLoad(Instruction*, PatchableJump& badType, IndexingType expectedShape = ContiguousShape); 342 JumpList emitArrayStorageLoad(Instruction*, PatchableJump& badType); 343 JumpList emitLoadForArrayMode(Instruction*, JITArrayMode, PatchableJump& badType); 344 330 345 JumpList emitInt32GetByVal(Instruction* instruction, PatchableJump& badType) { return emitContiguousGetByVal(instruction, badType, Int32Shape); } 331 346 JumpList emitDoubleGetByVal(Instruction*, PatchableJump& badType); … … 541 556 void emit_op_unsigned(Instruction*); 542 557 void emit_op_urshift(Instruction*); 558 void emit_op_get_enumerable_length(Instruction*); 559 void emit_op_has_generic_property(Instruction*); 560 void emit_op_has_structure_property(Instruction*); 561 void emit_op_has_indexed_property(Instruction*); 562 void emit_op_get_direct_pname(Instruction*); 563 void emit_op_get_structure_property_enumerator(Instruction*); 564 void emit_op_get_generic_property_enumerator(Instruction*); 565 void emit_op_next_enumerator_pname(Instruction*); 566 void emit_op_to_index_string(Instruction*); 543 567 544 568 void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&); … … 594 618 void emitSlow_op_unsigned(Instruction*, Vector<SlowCaseEntry>::iterator&); 595 619 void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&); 620 void emitSlow_op_has_indexed_property(Instruction*, Vector<SlowCaseEntry>::iterator&); 621 void emitSlow_op_has_structure_property(Instruction*, Vector<SlowCaseEntry>::iterator&); 622 void emitSlow_op_get_direct_pname(Instruction*, Vector<SlowCaseEntry>::iterator&); 596 623 597 624 void emit_op_resolve_scope(Instruction*); -
branches/ftlopt/Source/JavaScriptCore/jit/JITInlines.h
r167329 r171605 33 33 namespace JSC { 34 34 35 #if USE(JSVALUE64) 36 inline MacroAssembler::JumpList JIT::emitDoubleGetByVal(Instruction* instruction, PatchableJump& badType) 37 { 38 JumpList slowCases = emitDoubleLoad(instruction, badType); 39 moveDoubleTo64(fpRegT0, regT0); 40 sub64(tagTypeNumberRegister, regT0); 41 return slowCases; 42 } 43 #else 44 inline MacroAssembler::JumpList JIT::emitDoubleGetByVal(Instruction* instruction, PatchableJump& badType) 45 { 46 JumpList slowCases = emitDoubleLoad(instruction, badType); 47 moveDoubleToInts(fpRegT0, regT0, regT1); 48 return slowCases; 49 } 50 #endif // USE(JSVALUE64) 51 52 ALWAYS_INLINE MacroAssembler::JumpList JIT::emitLoadForArrayMode(Instruction* currentInstruction, JITArrayMode arrayMode, PatchableJump& badType) 53 { 54 switch (arrayMode) { 55 case JITInt32: 56 return emitInt32Load(currentInstruction, badType); 57 case JITDouble: 58 return emitDoubleLoad(currentInstruction, badType); 59 case JITContiguous: 60 return emitContiguousLoad(currentInstruction, badType); 61 case JITArrayStorage: 62 return emitArrayStorageLoad(currentInstruction, badType); 63 default: 64 RELEASE_ASSERT_NOT_REACHED(); 65 break; 66 } 67 } 68 69 inline MacroAssembler::JumpList JIT::emitContiguousGetByVal(Instruction* instruction, PatchableJump& badType, IndexingType expectedShape) 70 { 71 return emitContiguousLoad(instruction, badType, expectedShape); 72 } 73 74 inline MacroAssembler::JumpList JIT::emitArrayStorageGetByVal(Instruction* instruction, PatchableJump& badType) 75 { 76 return emitArrayStorageLoad(instruction, badType); 77 } 78 35 79 ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(int src) 36 80 { -
branches/ftlopt/Source/JavaScriptCore/jit/JITOpcodes.cpp
r168443 r171605 37 37 #include "JSCell.h" 38 38 #include "JSFunction.h" 39 #include "JSPropertyNameEnumerator.h" 39 40 #include "JSPropertyNameIterator.h" 40 41 #include "LinkBuffer.h" 41 42 #include "MaxFrameExtentForSlowPathCall.h" 43 #include "RepatchBuffer.h" 42 44 #include "SlowPathCall.h" 43 45 #include "VirtualRegister.h" … … 1211 1213 } 1212 1214 1215 #if USE(JSVALUE64) 1216 void JIT::emit_op_get_enumerable_length(Instruction* currentInstruction) 1217 { 1218 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_enumerable_length); 1219 slowPathCall.call(); 1220 } 1221 1222 void JIT::emit_op_has_structure_property(Instruction* currentInstruction) 1223 { 1224 int dst = currentInstruction[1].u.operand; 1225 int base = currentInstruction[2].u.operand; 1226 int enumerator = currentInstruction[4].u.operand; 1227 1228 emitGetVirtualRegister(base, regT0); 1229 emitGetVirtualRegister(enumerator, regT1); 1230 emitJumpSlowCaseIfNotJSCell(regT0, base); 1231 1232 load32(Address(regT0, JSCell::structureIDOffset()), regT0); 1233 addSlowCase(branch32(NotEqual, regT0, Address(regT1, JSPropertyNameEnumerator::cachedStructureIDOffset()))); 1234 1235 move(TrustedImm32(ValueTrue), regT0); 1236 emitPutVirtualRegister(dst); 1237 } 1238 1239 void JIT::emitSlow_op_has_structure_property(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1240 { 1241 linkSlowCase(iter); 1242 linkSlowCase(iter); 1243 1244 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_has_structure_property); 1245 slowPathCall.call(); 1246 } 1247 1248 void JIT::emit_op_has_generic_property(Instruction* currentInstruction) 1249 { 1250 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_has_generic_property); 1251 slowPathCall.call(); 1252 } 1253 1254 void JIT::privateCompileHasIndexedProperty(ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) 1255 { 1256 Instruction* currentInstruction = m_codeBlock->instructions().begin() + byValInfo->bytecodeIndex; 1257 1258 PatchableJump badType; 1259 1260 // FIXME: Add support for other types like TypedArrays and Arguments. 1261 // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034. 1262 JumpList slowCases = emitLoadForArrayMode(currentInstruction, arrayMode, badType); 1263 move(TrustedImm64(JSValue::encode(jsBoolean(true))), regT0); 1264 Jump done = jump(); 1265 1266 LinkBuffer patchBuffer(*m_vm, this, m_codeBlock); 1267 1268 patchBuffer.link(badType, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath)); 1269 patchBuffer.link(slowCases, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath)); 1270 1271 patchBuffer.link(done, byValInfo->badTypeJump.labelAtOffset(byValInfo->badTypeJumpToDone)); 1272 1273 byValInfo->stubRoutine = FINALIZE_CODE_FOR_STUB( 1274 m_codeBlock, patchBuffer, 1275 ("Baseline has_indexed_property stub for %s, return point %p", toCString(*m_codeBlock).data(), returnAddress.value())); 1276 1277 RepatchBuffer repatchBuffer(m_codeBlock); 1278 repatchBuffer.relink(byValInfo->badTypeJump, CodeLocationLabel(byValInfo->stubRoutine->code().code())); 1279 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(operationHasIndexedPropertyGeneric)); 1280 } 1281 1282 void JIT::emit_op_has_indexed_property(Instruction* currentInstruction) 1283 { 1284 int dst = currentInstruction[1].u.operand; 1285 int base = currentInstruction[2].u.operand; 1286 int property = currentInstruction[3].u.operand; 1287 ArrayProfile* profile = currentInstruction[4].u.arrayProfile; 1288 1289 emitGetVirtualRegisters(base, regT0, property, regT1); 1290 1291 // This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter. 1292 // We check the value as if it was a uint32 against the m_vectorLength - which will always fail if 1293 // number was signed since m_vectorLength is always less than intmax (since the total allocation 1294 // size is always less than 4Gb). As such zero extending will have been correct (and extending the value 1295 // to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign 1296 // extending since it makes it easier to re-tag the value in the slow case. 1297 zeroExtend32ToPtr(regT1, regT1); 1298 1299 emitJumpSlowCaseIfNotJSCell(regT0, base); 1300 emitArrayProfilingSiteWithCell(regT0, regT2, profile); 1301 and32(TrustedImm32(IndexingShapeMask), regT2); 1302 1303 JITArrayMode mode = chooseArrayMode(profile); 1304 PatchableJump badType; 1305 1306 // FIXME: Add support for other types like TypedArrays and Arguments. 1307 // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034. 1308 JumpList slowCases = emitLoadForArrayMode(currentInstruction, mode, badType); 1309 1310 move(TrustedImm64(JSValue::encode(jsBoolean(true))), regT0); 1311 1312 addSlowCase(badType); 1313 addSlowCase(slowCases); 1314 1315 Label done = label(); 1316 1317 emitPutVirtualRegister(dst); 1318 1319 m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done)); 1320 } 1321 1322 void JIT::emitSlow_op_has_indexed_property(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1323 { 1324 int dst = currentInstruction[1].u.operand; 1325 int base = currentInstruction[2].u.operand; 1326 int property = currentInstruction[3].u.operand; 1327 ArrayProfile* profile = currentInstruction[4].u.arrayProfile; 1328 1329 linkSlowCaseIfNotJSCell(iter, base); // base cell check 1330 linkSlowCase(iter); // base array check 1331 1332 Jump skipProfiling = jump(); 1333 1334 linkSlowCase(iter); // vector length check 1335 linkSlowCase(iter); // empty value 1336 1337 emitArrayProfileOutOfBoundsSpecialCase(profile); 1338 1339 skipProfiling.link(this); 1340 1341 Label slowPath = label(); 1342 1343 emitGetVirtualRegister(base, regT0); 1344 emitGetVirtualRegister(property, regT1); 1345 Call call = callOperation(operationHasIndexedPropertyDefault, dst, regT0, regT1); 1346 1347 m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath; 1348 m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call; 1349 m_byValInstructionIndex++; 1350 } 1351 1352 void JIT::emit_op_get_direct_pname(Instruction* currentInstruction) 1353 { 1354 int dst = currentInstruction[1].u.operand; 1355 int base = currentInstruction[2].u.operand; 1356 int index = currentInstruction[4].u.operand; 1357 int enumerator = currentInstruction[5].u.operand; 1358 1359 // Check that base is a cell 1360 emitGetVirtualRegister(base, regT0); 1361 emitJumpSlowCaseIfNotJSCell(regT0, base); 1362 1363 // Check the structure 1364 emitGetVirtualRegister(enumerator, regT2); 1365 load32(Address(regT0, JSCell::structureIDOffset()), regT1); 1366 addSlowCase(branch32(NotEqual, regT1, Address(regT2, JSPropertyNameEnumerator::cachedStructureIDOffset()))); 1367 1368 // Compute the offset 1369 emitGetVirtualRegister(index, regT1); 1370 // If index is less than the enumerator's cached inline storage, then it's an inline access 1371 Jump outOfLineAccess = branch32(AboveOrEqual, regT1, Address(regT2, JSPropertyNameEnumerator::cachedInlineCapacityOffset())); 1372 addPtr(TrustedImm32(JSObject::offsetOfInlineStorage()), regT0); 1373 signExtend32ToPtr(regT1, regT1); 1374 load64(BaseIndex(regT0, regT1, TimesEight), regT0); 1375 1376 Jump done = jump(); 1377 1378 // Otherwise it's out of line 1379 outOfLineAccess.link(this); 1380 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT0); 1381 sub32(Address(regT2, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), regT1); 1382 neg32(regT1); 1383 signExtend32ToPtr(regT1, regT1); 1384 int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue); 1385 load64(BaseIndex(regT0, regT1, TimesEight, offsetOfFirstProperty), regT0); 1386 1387 done.link(this); 1388 emitValueProfilingSite(); 1389 emitPutVirtualRegister(dst, regT0); 1390 } 1391 1392 void JIT::emitSlow_op_get_direct_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1393 { 1394 int base = currentInstruction[2].u.operand; 1395 linkSlowCaseIfNotJSCell(iter, base); 1396 linkSlowCase(iter); 1397 1398 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_direct_pname); 1399 slowPathCall.call(); 1400 } 1401 1402 void JIT::emit_op_get_structure_property_enumerator(Instruction* currentInstruction) 1403 { 1404 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_structure_property_enumerator); 1405 slowPathCall.call(); 1406 } 1407 1408 void JIT::emit_op_get_generic_property_enumerator(Instruction* currentInstruction) 1409 { 1410 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_generic_property_enumerator); 1411 slowPathCall.call(); 1412 } 1413 1414 void JIT::emit_op_next_enumerator_pname(Instruction* currentInstruction) 1415 { 1416 int dst = currentInstruction[1].u.operand; 1417 int enumerator = currentInstruction[2].u.operand; 1418 int index = currentInstruction[3].u.operand; 1419 1420 emitGetVirtualRegister(index, regT0); 1421 emitGetVirtualRegister(enumerator, regT1); 1422 Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset())); 1423 1424 move(TrustedImm32(ValueNull), regT0); 1425 1426 Jump done = jump(); 1427 inBounds.link(this); 1428 1429 loadPtr(Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), regT1); 1430 signExtend32ToPtr(regT0, regT0); 1431 load64(BaseIndex(regT1, regT0, TimesEight), regT0); 1432 1433 done.link(this); 1434 emitPutVirtualRegister(dst); 1435 } 1436 1437 void JIT::emit_op_to_index_string(Instruction* currentInstruction) 1438 { 1439 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_index_string); 1440 slowPathCall.call(); 1441 } 1442 #endif // USE(JSVALUE64) 1443 1213 1444 } // namespace JSC 1214 1445 -
branches/ftlopt/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r167646 r171605 37 37 #include "JSCell.h" 38 38 #include "JSFunction.h" 39 #include "JSPropertyNameEnumerator.h" 39 40 #include "JSPropertyNameIterator.h" 40 41 #include "JSVariableObject.h" 41 42 #include "LinkBuffer.h" 42 43 #include "MaxFrameExtentForSlowPathCall.h" 44 #include "RepatchBuffer.h" 43 45 #include "SlowPathCall.h" 44 46 #include "VirtualRegister.h" … … 1177 1179 } 1178 1180 1181 void JIT::emit_op_get_enumerable_length(Instruction* currentInstruction) 1182 { 1183 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_enumerable_length); 1184 slowPathCall.call(); 1185 } 1186 1187 void JIT::emit_op_has_structure_property(Instruction* currentInstruction) 1188 { 1189 int dst = currentInstruction[1].u.operand; 1190 int base = currentInstruction[2].u.operand; 1191 int enumerator = currentInstruction[4].u.operand; 1192 1193 emitLoadPayload(base, regT0); 1194 emitJumpSlowCaseIfNotJSCell(base); 1195 1196 emitLoadPayload(enumerator, regT1); 1197 1198 load32(Address(regT0, JSCell::structureIDOffset()), regT0); 1199 addSlowCase(branch32(NotEqual, regT0, Address(regT1, JSPropertyNameEnumerator::cachedStructureIDOffset()))); 1200 1201 move(TrustedImm32(1), regT0); 1202 emitStoreBool(dst, regT0); 1203 } 1204 1205 void JIT::emitSlow_op_has_structure_property(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1206 { 1207 linkSlowCase(iter); 1208 linkSlowCase(iter); 1209 1210 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_has_structure_property); 1211 slowPathCall.call(); 1212 } 1213 1214 void JIT::emit_op_has_generic_property(Instruction* currentInstruction) 1215 { 1216 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_has_generic_property); 1217 slowPathCall.call(); 1218 } 1219 1220 void JIT::privateCompileHasIndexedProperty(ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) 1221 { 1222 Instruction* currentInstruction = m_codeBlock->instructions().begin() + byValInfo->bytecodeIndex; 1223 1224 PatchableJump badType; 1225 1226 // FIXME: Add support for other types like TypedArrays and Arguments. 1227 // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034. 1228 JumpList slowCases = emitLoadForArrayMode(currentInstruction, arrayMode, badType); 1229 move(TrustedImm32(1), regT0); 1230 Jump done = jump(); 1231 1232 LinkBuffer patchBuffer(*m_vm, this, m_codeBlock); 1233 1234 patchBuffer.link(badType, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath)); 1235 patchBuffer.link(slowCases, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath)); 1236 1237 patchBuffer.link(done, byValInfo->badTypeJump.labelAtOffset(byValInfo->badTypeJumpToDone)); 1238 1239 byValInfo->stubRoutine = FINALIZE_CODE_FOR_STUB( 1240 m_codeBlock, patchBuffer, 1241 ("Baseline has_indexed_property stub for %s, return point %p", toCString(*m_codeBlock).data(), returnAddress.value())); 1242 1243 RepatchBuffer repatchBuffer(m_codeBlock); 1244 repatchBuffer.relink(byValInfo->badTypeJump, CodeLocationLabel(byValInfo->stubRoutine->code().code())); 1245 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(operationHasIndexedPropertyGeneric)); 1246 } 1247 1248 void JIT::emit_op_has_indexed_property(Instruction* currentInstruction) 1249 { 1250 int dst = currentInstruction[1].u.operand; 1251 int base = currentInstruction[2].u.operand; 1252 int property = currentInstruction[3].u.operand; 1253 ArrayProfile* profile = currentInstruction[4].u.arrayProfile; 1254 1255 emitLoadPayload(base, regT0); 1256 emitJumpSlowCaseIfNotJSCell(base); 1257 1258 emitLoadPayload(property, regT1); 1259 1260 // This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter. 1261 // We check the value as if it was a uint32 against the m_vectorLength - which will always fail if 1262 // number was signed since m_vectorLength is always less than intmax (since the total allocation 1263 // size is always less than 4Gb). As such zero extending will have been correct (and extending the value 1264 // to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign 1265 // extending since it makes it easier to re-tag the value in the slow case. 1266 zeroExtend32ToPtr(regT1, regT1); 1267 1268 emitArrayProfilingSiteWithCell(regT0, regT2, profile); 1269 and32(TrustedImm32(IndexingShapeMask), regT2); 1270 1271 JITArrayMode mode = chooseArrayMode(profile); 1272 PatchableJump badType; 1273 1274 // FIXME: Add support for other types like TypedArrays and Arguments. 1275 // See https://bugs.webkit.org/show_bug.cgi?id=135033 and https://bugs.webkit.org/show_bug.cgi?id=135034. 1276 JumpList slowCases = emitLoadForArrayMode(currentInstruction, mode, badType); 1277 move(TrustedImm32(1), regT0); 1278 1279 addSlowCase(badType); 1280 addSlowCase(slowCases); 1281 1282 Label done = label(); 1283 1284 emitStoreBool(dst, regT0); 1285 1286 m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done)); 1287 } 1288 1289 void JIT::emitSlow_op_has_indexed_property(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1290 { 1291 int dst = currentInstruction[1].u.operand; 1292 int base = currentInstruction[2].u.operand; 1293 int property = currentInstruction[3].u.operand; 1294 ArrayProfile* profile = currentInstruction[4].u.arrayProfile; 1295 1296 linkSlowCaseIfNotJSCell(iter, base); // base cell check 1297 linkSlowCase(iter); // base array check 1298 1299 Jump skipProfiling = jump(); 1300 1301 linkSlowCase(iter); // vector length check 1302 linkSlowCase(iter); // empty value 1303 1304 emitArrayProfileOutOfBoundsSpecialCase(profile); 1305 1306 skipProfiling.link(this); 1307 1308 Label slowPath = label(); 1309 1310 emitLoad(base, regT1, regT0); 1311 emitLoad(property, regT3, regT2); 1312 Call call = callOperation(operationHasIndexedPropertyDefault, dst, regT1, regT0, regT3, regT2); 1313 1314 m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath; 1315 m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call; 1316 m_byValInstructionIndex++; 1317 } 1318 1319 void JIT::emit_op_get_direct_pname(Instruction* currentInstruction) 1320 { 1321 int dst = currentInstruction[1].u.operand; 1322 int base = currentInstruction[2].u.operand; 1323 int index = currentInstruction[4].u.operand; 1324 int enumerator = currentInstruction[5].u.operand; 1325 1326 // Check that base is a cell 1327 emitLoadPayload(base, regT0); 1328 emitJumpSlowCaseIfNotJSCell(base); 1329 1330 // Check the structure 1331 emitLoadPayload(enumerator, regT1); 1332 load32(Address(regT0, JSCell::structureIDOffset()), regT2); 1333 addSlowCase(branch32(NotEqual, regT2, Address(regT1, JSPropertyNameEnumerator::cachedStructureIDOffset()))); 1334 1335 // Compute the offset 1336 emitLoadPayload(index, regT2); 1337 // If index is less than the enumerator's cached inline storage, then it's an inline access 1338 Jump outOfLineAccess = branch32(AboveOrEqual, regT2, Address(regT1, JSPropertyNameEnumerator::cachedInlineCapacityOffset())); 1339 addPtr(TrustedImm32(JSObject::offsetOfInlineStorage()), regT0); 1340 load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); 1341 load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); 1342 1343 Jump done = jump(); 1344 1345 // Otherwise it's out of line 1346 outOfLineAccess.link(this); 1347 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT0); 1348 sub32(Address(regT1, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), regT2); 1349 neg32(regT2); 1350 int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue); 1351 load32(BaseIndex(regT0, regT2, TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); 1352 load32(BaseIndex(regT0, regT2, TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); 1353 1354 done.link(this); 1355 emitValueProfilingSite(); 1356 emitStore(dst, regT1, regT0); 1357 } 1358 1359 void JIT::emitSlow_op_get_direct_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1360 { 1361 int base = currentInstruction[2].u.operand; 1362 linkSlowCaseIfNotJSCell(iter, base); 1363 linkSlowCase(iter); 1364 1365 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_direct_pname); 1366 slowPathCall.call(); 1367 } 1368 1369 void JIT::emit_op_get_structure_property_enumerator(Instruction* currentInstruction) 1370 { 1371 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_structure_property_enumerator); 1372 slowPathCall.call(); 1373 } 1374 1375 void JIT::emit_op_get_generic_property_enumerator(Instruction* currentInstruction) 1376 { 1377 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_generic_property_enumerator); 1378 slowPathCall.call(); 1379 } 1380 1381 void JIT::emit_op_next_enumerator_pname(Instruction* currentInstruction) 1382 { 1383 int dst = currentInstruction[1].u.operand; 1384 int enumerator = currentInstruction[2].u.operand; 1385 int index = currentInstruction[3].u.operand; 1386 1387 emitLoadPayload(index, regT0); 1388 emitLoadPayload(enumerator, regT1); 1389 Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset())); 1390 1391 move(TrustedImm32(JSValue::NullTag), regT2); 1392 move(TrustedImm32(0), regT0); 1393 1394 Jump done = jump(); 1395 inBounds.link(this); 1396 1397 loadPtr(Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), regT1); 1398 loadPtr(BaseIndex(regT1, regT0, timesPtr()), regT0); 1399 move(TrustedImm32(JSValue::CellTag), regT2); 1400 1401 done.link(this); 1402 emitStore(dst, regT2, regT0); 1403 } 1404 1405 void JIT::emit_op_to_index_string(Instruction* currentInstruction) 1406 { 1407 JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_to_index_string); 1408 slowPathCall.call(); 1409 } 1410 1179 1411 } // namespace JSC 1180 1412 -
branches/ftlopt/Source/JavaScriptCore/jit/JITOperations.cpp
r171389 r171605 45 45 #include "JSGlobalObjectFunctions.h" 46 46 #include "JSNameScope.h" 47 #include "JSPropertyNameEnumerator.h" 47 48 #include "JSPropertyNameIterator.h" 48 49 #include "JSStackInlines.h" … … 1499 1500 } 1500 1501 1502 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) 1503 { 1504 VM& vm = exec->vm(); 1505 NativeCallFrameTracer tracer(&vm, exec); 1506 JSValue baseValue = JSValue::decode(encodedBase); 1507 JSValue subscript = JSValue::decode(encodedSubscript); 1508 1509 ASSERT(baseValue.isObject()); 1510 ASSERT(subscript.isUInt32()); 1511 1512 JSObject* object = asObject(baseValue); 1513 bool didOptimize = false; 1514 1515 unsigned bytecodeOffset = exec->locationAsBytecodeOffset(); 1516 ASSERT(bytecodeOffset); 1517 ByValInfo& byValInfo = exec->codeBlock()->getByValInfo(bytecodeOffset - 1); 1518 ASSERT(!byValInfo.stubRoutine); 1519 1520 if (hasOptimizableIndexing(object->structure(vm))) { 1521 // Attempt to optimize. 1522 JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm)); 1523 if (arrayMode != byValInfo.arrayMode) { 1524 JIT::compileHasIndexedProperty(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode); 1525 didOptimize = true; 1526 } 1527 } 1528 1529 if (!didOptimize) { 1530 // If we take slow path more than 10 times without patching then make sure we 1531 // never make that mistake again. Or, if we failed to patch and we have some object 1532 // that intercepts indexed get, then don't even wait until 10 times. For cases 1533 // where we see non-index-intercepting objects, this gives 10 iterations worth of 1534 // opportunity for us to observe that the get_by_val may be polymorphic. 1535 if (++byValInfo.slowPathCount >= 10 1536 || object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) { 1537 // Don't ever try to optimize. 1538 RepatchBuffer repatchBuffer(exec->codeBlock()); 1539 repatchBuffer.relinkCallerToFunction(ReturnAddressPtr(OUR_RETURN_ADDRESS), FunctionPtr(operationHasIndexedPropertyGeneric)); 1540 } 1541 } 1542 1543 return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript.asUInt32()))); 1544 } 1545 1546 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) 1547 { 1548 VM& vm = exec->vm(); 1549 NativeCallFrameTracer tracer(&vm, exec); 1550 JSValue baseValue = JSValue::decode(encodedBase); 1551 JSValue subscript = JSValue::decode(encodedSubscript); 1552 1553 ASSERT(baseValue.isObject()); 1554 ASSERT(subscript.isUInt32()); 1555 1556 JSObject* object = asObject(baseValue); 1557 return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript.asUInt32()))); 1558 } 1559 1501 1560 EncodedJSValue JIT_OPERATION operationGetByValString(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) 1502 1561 { … … 1797 1856 ASSERT(!exec->isVMEntrySentinel()); 1798 1857 genericUnwind(vm, exec, vm->exception()); 1858 } 1859 1860 int32_t JIT_OPERATION operationGetEnumerableLength(ExecState* exec, JSCell* baseCell) 1861 { 1862 VM& vm = exec->vm(); 1863 NativeCallFrameTracer tracer(&vm, exec); 1864 JSObject* base = baseCell->toObject(exec, exec->lexicalGlobalObject()); 1865 return base->methodTable(vm)->getEnumerableLength(exec, base); 1866 } 1867 1868 EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* propertyName) 1869 { 1870 VM& vm = exec->vm(); 1871 NativeCallFrameTracer tracer(&vm, exec); 1872 JSValue baseValue = JSValue::decode(encodedBaseValue); 1873 if (baseValue.isUndefinedOrNull()) 1874 return JSValue::encode(jsBoolean(false)); 1875 1876 JSObject* base = baseValue.toObject(exec); 1877 return JSValue::encode(jsBoolean(base->hasProperty(exec, asString(propertyName)->toIdentifier(exec)))); 1878 } 1879 1880 EncodedJSValue JIT_OPERATION operationHasIndexedProperty(ExecState* exec, JSCell* baseCell, int32_t subscript) 1881 { 1882 VM& vm = exec->vm(); 1883 NativeCallFrameTracer tracer(&vm, exec); 1884 JSObject* object = baseCell->toObject(exec, exec->lexicalGlobalObject()); 1885 return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript))); 1886 } 1887 1888 JSCell* JIT_OPERATION operationGetStructurePropertyEnumerator(ExecState* exec, JSCell* cell, int32_t length) 1889 { 1890 VM& vm = exec->vm(); 1891 NativeCallFrameTracer tracer(&vm, exec); 1892 1893 JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject()); 1894 ASSERT(length >= 0); 1895 1896 return structurePropertyNameEnumerator(exec, base, static_cast<uint32_t>(length)); 1897 } 1898 1899 JSCell* JIT_OPERATION operationGetGenericPropertyEnumerator(ExecState* exec, JSCell* baseCell, int32_t length, JSCell* structureEnumeratorCell) 1900 { 1901 VM& vm = exec->vm(); 1902 NativeCallFrameTracer tracer(&vm, exec); 1903 1904 JSObject* base = baseCell->toObject(exec, exec->lexicalGlobalObject()); 1905 ASSERT(length >= 0); 1906 1907 return genericPropertyNameEnumerator(exec, base, length, jsCast<JSPropertyNameEnumerator*>(structureEnumeratorCell)); 1908 } 1909 1910 EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState* exec, JSCell* enumeratorCell, int32_t index) 1911 { 1912 VM& vm = exec->vm(); 1913 NativeCallFrameTracer tracer(&vm, exec); 1914 JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorCell); 1915 JSString* propertyName = enumerator->propertyNameAtIndex(index); 1916 return JSValue::encode(propertyName ? propertyName : jsNull()); 1917 } 1918 1919 JSCell* JIT_OPERATION operationToIndexString(ExecState* exec, int32_t index) 1920 { 1921 VM& vm = exec->vm(); 1922 NativeCallFrameTracer tracer(&vm, exec); 1923 return jsString(exec, Identifier::from(exec, index).string()); 1799 1924 } 1800 1925 -
branches/ftlopt/Source/JavaScriptCore/jit/JITOperations.h
r170736 r171605 97 97 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ECI)(ExecState*, JSCell*, StringImpl*); 98 98 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue); 99 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_ECZ)(ExecState*, JSCell*, int32_t); 99 100 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EDA)(ExecState*, double, JSArray*); 100 101 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EE)(ExecState*, ExecState*); 101 102 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EI)(ExecState*, StringImpl*); 102 103 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJ)(ExecState*, EncodedJSValue); 104 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t); 105 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJC)(ExecState*, EncodedJSValue, JSCell*); 103 106 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJA)(ExecState*, EncodedJSValue, JSArray*); 104 107 typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJIdc)(ExecState*, EncodedJSValue, const Identifier*); … … 119 122 typedef JSCell* JIT_OPERATION (*C_JITOperation_EZ)(ExecState*, int32_t); 120 123 typedef JSCell* JIT_OPERATION (*C_JITOperation_EC)(ExecState*, JSCell*); 124 typedef JSCell* JIT_OPERATION (*C_JITOperation_ECZ)(ExecState*, JSCell*, int32_t); 125 typedef JSCell* JIT_OPERATION (*C_JITOperation_ECZC)(ExecState*, JSCell*, int32_t, JSCell*); 121 126 typedef JSCell* JIT_OPERATION (*C_JITOperation_ECC)(ExecState*, JSCell*, JSCell*); 122 127 typedef JSCell* JIT_OPERATION (*C_JITOperation_EIcf)(ExecState*, InlineCallFrame*); 123 128 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJ)(ExecState*, EncodedJSValue); 129 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJZ)(ExecState*, EncodedJSValue, int32_t); 130 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJZC)(ExecState*, EncodedJSValue, int32_t, JSCell*); 131 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJJC)(ExecState*, EncodedJSValue, EncodedJSValue, JSCell*); 124 132 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJssSt)(ExecState*, JSString*, Structure*); 125 133 typedef JSCell* JIT_OPERATION (*C_JITOperation_EJssJss)(ExecState*, JSString*, JSString*); … … 135 143 typedef int32_t JIT_OPERATION (*Z_JITOperation_D)(double); 136 144 typedef int32_t JIT_OPERATION (*Z_JITOperation_E)(ExecState*); 145 typedef int32_t JIT_OPERATION (*Z_JITOperation_EC)(ExecState*, JSCell*); 137 146 typedef size_t JIT_OPERATION (*S_JITOperation_ECC)(ExecState*, JSCell*, JSCell*); 138 147 typedef size_t JIT_OPERATION (*S_JITOperation_EJ)(ExecState*, EncodedJSValue); … … 278 287 EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL; 279 288 EncodedJSValue JIT_OPERATION operationGetByValString(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL; 289 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL; 290 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL; 280 291 void JIT_OPERATION operationTearOffActivation(ExecState*, JSCell*) WTF_INTERNAL; 281 292 void JIT_OPERATION operationTearOffArguments(ExecState*, JSCell*, JSCell*) WTF_INTERNAL; … … 300 311 301 312 void JIT_OPERATION operationInitGlobalConst(ExecState*, Instruction*); 313 314 int32_t JIT_OPERATION operationGetEnumerableLength(ExecState*, JSCell*); 315 EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState*, EncodedJSValue, JSCell*); 316 EncodedJSValue JIT_OPERATION operationHasIndexedProperty(ExecState*, JSCell*, int32_t); 317 JSCell* JIT_OPERATION operationGetStructurePropertyEnumerator(ExecState*, JSCell*, int32_t); 318 JSCell* JIT_OPERATION operationGetGenericPropertyEnumerator(ExecState*, JSCell*, int32_t, JSCell*); 319 EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState*, JSCell*, int32_t); 320 JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t); 302 321 303 322 } // extern "C" -
branches/ftlopt/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r169143 r171605 152 152 } 153 153 154 JIT::JumpList JIT::emitDouble GetByVal(Instruction*, PatchableJump& badType)154 JIT::JumpList JIT::emitDoubleLoad(Instruction*, PatchableJump& badType) 155 155 { 156 156 JumpList slowCases; … … 161 161 loadDouble(BaseIndex(regT2, regT1, TimesEight), fpRegT0); 162 162 slowCases.append(branchDouble(DoubleNotEqualOrUnordered, fpRegT0, fpRegT0)); 163 moveDoubleTo64(fpRegT0, regT0);164 sub64(tagTypeNumberRegister, regT0);165 163 166 164 return slowCases; 167 165 } 168 166 169 JIT::JumpList JIT::emitContiguous GetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape)167 JIT::JumpList JIT::emitContiguousLoad(Instruction*, PatchableJump& badType, IndexingType expectedShape) 170 168 { 171 169 JumpList slowCases; … … 180 178 } 181 179 182 JIT::JumpList JIT::emitArrayStorage GetByVal(Instruction*, PatchableJump& badType)180 JIT::JumpList JIT::emitArrayStorageLoad(Instruction*, PatchableJump& badType) 183 181 { 184 182 JumpList slowCases; -
branches/ftlopt/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r168443 r171605 174 174 } 175 175 176 JIT::JumpList JIT::emitContiguous GetByVal(Instruction*, PatchableJump& badType, IndexingType expectedShape)176 JIT::JumpList JIT::emitContiguousLoad(Instruction*, PatchableJump& badType, IndexingType expectedShape) 177 177 { 178 178 JumpList slowCases; 179 179 180 180 badType = patchableBranch32(NotEqual, regT1, TrustedImm32(expectedShape)); 181 182 181 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); 183 182 slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, Butterfly::offsetOfPublicLength()))); 184 185 183 load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag 186 184 load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload … … 190 188 } 191 189 192 JIT::JumpList JIT::emitDouble GetByVal(Instruction*, PatchableJump& badType)190 JIT::JumpList JIT::emitDoubleLoad(Instruction*, PatchableJump& badType) 193 191 { 194 192 JumpList slowCases; 195 193 196 194 badType = patchableBranch32(NotEqual, regT1, TrustedImm32(DoubleShape)); 197 198 195 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); 199 196 slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, Butterfly::offsetOfPublicLength()))); 200 201 197 loadDouble(BaseIndex(regT3, regT2, TimesEight), fpRegT0); 202 198 slowCases.append(branchDouble(DoubleNotEqualOrUnordered, fpRegT0, fpRegT0)); 203 moveDoubleToInts(fpRegT0, regT0, regT1);204 199 205 200 return slowCases; 206 201 } 207 202 208 JIT::JumpList JIT::emitArrayStorage GetByVal(Instruction*, PatchableJump& badType)203 JIT::JumpList JIT::emitArrayStorageLoad(Instruction*, PatchableJump& badType) 209 204 { 210 205 JumpList slowCases; … … 212 207 add32(TrustedImm32(-ArrayStorageShape), regT1, regT3); 213 208 badType = patchableBranch32(Above, regT3, TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)); 214 215 209 loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); 216 210 slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset()))); 217 218 211 load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag 219 212 load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload -
branches/ftlopt/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r170836 r171605 1211 1211 nativeCallTrampoline(NativeExecutable::m_constructor) 1212 1212 1213 _llint_op_get_enumerable_length: 1214 traceExecution() 1215 callSlowPath(_slow_path_get_enumerable_length) 1216 dispatch(3) 1217 1218 _llint_op_has_indexed_property: 1219 traceExecution() 1220 callSlowPath(_slow_path_has_indexed_property) 1221 dispatch(5) 1222 1223 _llint_op_has_structure_property: 1224 traceExecution() 1225 callSlowPath(_slow_path_has_structure_property) 1226 dispatch(5) 1227 1228 _llint_op_has_generic_property: 1229 traceExecution() 1230 callSlowPath(_slow_path_has_generic_property) 1231 dispatch(4) 1232 1233 _llint_op_get_direct_pname: 1234 traceExecution() 1235 callSlowPath(_slow_path_get_direct_pname) 1236 dispatch(7) 1237 1238 _llint_op_get_structure_property_enumerator: 1239 traceExecution() 1240 callSlowPath(_slow_path_get_structure_property_enumerator) 1241 dispatch(4) 1242 1243 _llint_op_get_generic_property_enumerator: 1244 traceExecution() 1245 callSlowPath(_slow_path_get_generic_property_enumerator) 1246 dispatch(5) 1247 1248 _llint_op_next_enumerator_pname: 1249 traceExecution() 1250 callSlowPath(_slow_path_next_enumerator_pname) 1251 dispatch(4) 1252 1253 _llint_op_to_index_string: 1254 traceExecution() 1255 callSlowPath(_slow_path_to_index_string) 1256 dispatch(3) 1213 1257 1214 1258 # Lastly, make sure that we can link even though we don't support all opcodes. -
branches/ftlopt/Source/JavaScriptCore/parser/Nodes.h
r168107 r171605 1281 1281 1282 1282 private: 1283 RegisterID* tryGetBoundLocal(BytecodeGenerator&); 1284 void emitLoopHeader(BytecodeGenerator&, RegisterID* propertyName); 1285 void emitMultiLoopBytecode(BytecodeGenerator&, RegisterID* dst); 1286 1283 1287 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1284 1288 }; -
branches/ftlopt/Source/JavaScriptCore/runtime/Arguments.cpp
r167729 r171605 224 224 propertyNames.add(Identifier::from(exec, i)); 225 225 } 226 if ( mode == IncludeDontEnumProperties) {226 if (shouldIncludeDontEnumProperties(mode)) { 227 227 propertyNames.add(exec->propertyNames().callee); 228 228 propertyNames.add(exec->propertyNames().length); -
branches/ftlopt/Source/JavaScriptCore/runtime/ClassInfo.h
r166837 r171605 82 82 typedef void (*GetPropertyNamesFunctionPtr)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 83 83 GetPropertyNamesFunctionPtr getPropertyNames; 84 85 typedef uint32_t (*GetEnumerableLengthFunctionPtr)(ExecState*, JSObject*); 86 GetEnumerableLengthFunctionPtr getEnumerableLength; 87 88 GetPropertyNamesFunctionPtr getStructurePropertyNames; 89 GetPropertyNamesFunctionPtr getGenericPropertyNames; 84 90 85 91 typedef String (*ClassNameFunctionPtr)(const JSObject*); … … 138 144 &ClassName::getOwnNonIndexPropertyNames, \ 139 145 &ClassName::getPropertyNames, \ 146 &ClassName::getEnumerableLength, \ 147 &ClassName::getStructurePropertyNames, \ 148 &ClassName::getGenericPropertyNames, \ 140 149 &ClassName::className, \ 141 150 &ClassName::customHasInstance, \ -
branches/ftlopt/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r170564 r171605 45 45 #include "JSGlobalObjectFunctions.h" 46 46 #include "JSNameScope.h" 47 #include "JSPropertyNameEnumerator.h" 47 48 #include "JSPropertyNameIterator.h" 48 49 #include "JSString.h" … … 543 544 } 544 545 546 SLOW_PATH_DECL(slow_path_get_enumerable_length) 547 { 548 BEGIN(); 549 JSValue baseValue = OP(2).jsValue(); 550 if (baseValue.isUndefinedOrNull()) 551 RETURN(jsNumber(0)); 552 553 JSObject* base = baseValue.toObject(exec); 554 RETURN(jsNumber(base->methodTable(vm)->getEnumerableLength(exec, base))); 555 } 556 557 SLOW_PATH_DECL(slow_path_has_indexed_property) 558 { 559 BEGIN(); 560 JSObject* base = OP(2).jsValue().toObject(exec); 561 JSValue property = OP(3).jsValue(); 562 pc[4].u.arrayProfile->observeStructure(base->structure(vm)); 563 ASSERT(property.isUInt32()); 564 RETURN(jsBoolean(base->hasProperty(exec, property.asUInt32()))); 565 } 566 567 SLOW_PATH_DECL(slow_path_has_structure_property) 568 { 569 BEGIN(); 570 JSObject* base = OP(2).jsValue().toObject(exec); 571 JSValue property = OP(3).jsValue(); 572 ASSERT(property.isString()); 573 JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(4).jsValue().asCell()); 574 if (base->structure(vm)->id() == enumerator->cachedStructureID()) 575 RETURN(jsBoolean(true)); 576 RETURN(jsBoolean(base->hasProperty(exec, asString(property.asCell())->toIdentifier(exec)))); 577 } 578 579 SLOW_PATH_DECL(slow_path_has_generic_property) 580 { 581 BEGIN(); 582 JSObject* base = OP(2).jsValue().toObject(exec); 583 JSValue property = OP(3).jsValue(); 584 bool result; 585 if (property.isString()) 586 result = base->hasProperty(exec, asString(property.asCell())->toIdentifier(exec)); 587 else { 588 ASSERT(property.isUInt32()); 589 result = base->hasProperty(exec, property.asUInt32()); 590 } 591 RETURN(jsBoolean(result)); 592 } 593 594 SLOW_PATH_DECL(slow_path_get_direct_pname) 595 { 596 BEGIN(); 597 JSValue baseValue = OP(2).jsValue(); 598 JSValue property = OP(3).jsValue(); 599 ASSERT(property.isString()); 600 RETURN(baseValue.get(exec, property.toString(exec)->toIdentifier(exec))); 601 } 602 603 SLOW_PATH_DECL(slow_path_get_structure_property_enumerator) 604 { 605 BEGIN(); 606 JSValue baseValue = OP(2).jsValue(); 607 if (baseValue.isUndefinedOrNull()) 608 RETURN(JSPropertyNameEnumerator::create(vm)); 609 610 JSObject* base = baseValue.toObject(exec); 611 uint32_t length = OP(3).jsValue().asUInt32(); 612 613 RETURN(structurePropertyNameEnumerator(exec, base, length)); 614 } 615 616 SLOW_PATH_DECL(slow_path_get_generic_property_enumerator) 617 { 618 BEGIN(); 619 JSValue baseValue = OP(2).jsValue(); 620 if (baseValue.isUndefinedOrNull()) 621 RETURN(JSPropertyNameEnumerator::create(vm)); 622 623 JSObject* base = baseValue.toObject(exec); 624 uint32_t length = OP(3).jsValue().asUInt32(); 625 JSPropertyNameEnumerator* structureEnumerator = jsCast<JSPropertyNameEnumerator*>(OP(4).jsValue().asCell()); 626 627 RETURN(genericPropertyNameEnumerator(exec, base, length, structureEnumerator)); 628 } 629 630 SLOW_PATH_DECL(slow_path_next_enumerator_pname) 631 { 632 BEGIN(); 633 JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(2).jsValue().asCell()); 634 uint32_t index = OP(3).jsValue().asUInt32(); 635 JSString* propertyName = enumerator->propertyNameAtIndex(index); 636 RETURN(propertyName ? propertyName : jsNull()); 637 } 638 639 SLOW_PATH_DECL(slow_path_to_index_string) 640 { 641 BEGIN(); 642 RETURN(jsString(exec, Identifier::from(exec, OP(2).jsValue().asUInt32()).string())); 643 } 644 545 645 } // namespace JSC 546 646 -
branches/ftlopt/Source/JavaScriptCore/runtime/CommonSlowPaths.h
r170855 r171605 227 227 SLOW_PATH_HIDDEN_DECL(slow_path_strcat); 228 228 SLOW_PATH_HIDDEN_DECL(slow_path_to_primitive); 229 SLOW_PATH_HIDDEN_DECL(slow_path_get_enumerable_length); 230 SLOW_PATH_HIDDEN_DECL(slow_path_has_generic_property); 231 SLOW_PATH_HIDDEN_DECL(slow_path_has_structure_property); 232 SLOW_PATH_HIDDEN_DECL(slow_path_has_indexed_property); 233 SLOW_PATH_HIDDEN_DECL(slow_path_get_direct_pname); 234 SLOW_PATH_HIDDEN_DECL(slow_path_get_structure_property_enumerator); 235 SLOW_PATH_HIDDEN_DECL(slow_path_get_generic_property_enumerator); 236 SLOW_PATH_HIDDEN_DECL(slow_path_next_enumerator_pname); 237 SLOW_PATH_HIDDEN_DECL(slow_path_to_index_string); 229 238 230 239 } // namespace JSC -
branches/ftlopt/Source/JavaScriptCore/runtime/JSActivation.cpp
r165676 r171605 112 112 113 113 CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers)); 114 if ( mode == IncludeDontEnumProperties&& !thisObject->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval()))114 if (shouldIncludeDontEnumProperties(mode) && !thisObject->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())) 115 115 propertyNames.add(exec->propertyNames().arguments); 116 116 … … 119 119 SymbolTable::Map::iterator end = thisObject->symbolTable()->end(locker); 120 120 for (SymbolTable::Map::iterator it = thisObject->symbolTable()->begin(locker); it != end; ++it) { 121 if (it->value.getAttributes() & DontEnum && mode != IncludeDontEnumProperties)121 if (it->value.getAttributes() & DontEnum && !shouldIncludeDontEnumProperties(mode)) 122 122 continue; 123 123 if (!thisObject->isValid(it->value)) -
branches/ftlopt/Source/JavaScriptCore/runtime/JSArray.cpp
r170628 r171605 228 228 JSArray* thisObject = jsCast<JSArray*>(object); 229 229 230 if ( mode == IncludeDontEnumProperties)230 if (shouldIncludeDontEnumProperties(mode)) 231 231 propertyNames.add(exec->propertyNames().length); 232 232 -
branches/ftlopt/Source/JavaScriptCore/runtime/JSArrayBuffer.cpp
r163844 r171605 120 120 JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(object); 121 121 122 if ( mode == IncludeDontEnumProperties)122 if (shouldIncludeDontEnumProperties(mode)) 123 123 array.add(exec->propertyNames().byteLength); 124 124 -
branches/ftlopt/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp
r163844 r171605 202 202 203 203 // length/byteOffset/byteLength are DontEnum, at least in Firefox. 204 if ( mode == IncludeDontEnumProperties) {204 if (shouldIncludeDontEnumProperties(mode)) { 205 205 array.add(exec->propertyNames().byteOffset); 206 206 array.add(exec->propertyNames().byteLength); -
branches/ftlopt/Source/JavaScriptCore/runtime/JSCell.cpp
r166837 r171605 237 237 } 238 238 239 uint32_t JSCell::getEnumerableLength(ExecState*, JSObject*) 240 { 241 RELEASE_ASSERT_NOT_REACHED(); 242 } 243 244 void JSCell::getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) 245 { 246 RELEASE_ASSERT_NOT_REACHED(); 247 } 248 249 void JSCell::getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode) 250 { 251 RELEASE_ASSERT_NOT_REACHED(); 252 } 253 239 254 } // namespace JSC -
branches/ftlopt/Source/JavaScriptCore/runtime/JSCell.h
r168335 r171605 26 26 #include "CallData.h" 27 27 #include "ConstructData.h" 28 #include "EnumerationMode.h" 28 29 #include "Heap.h" 29 30 #include "IndexingType.h" … … 46 47 class PropertyNameArray; 47 48 class Structure; 48 49 enum EnumerationMode {50 ExcludeDontEnumProperties,51 IncludeDontEnumProperties52 };53 49 54 50 template<typename T> void* allocateCell(Heap&); … … 210 206 static NO_RETURN_DUE_TO_CRASH void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 211 207 static NO_RETURN_DUE_TO_CRASH void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 208 209 static NO_RETURN_DUE_TO_CRASH uint32_t getEnumerableLength(ExecState*, JSObject*); 210 static NO_RETURN_DUE_TO_CRASH void getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 211 static NO_RETURN_DUE_TO_CRASH void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 212 212 213 static String className(const JSObject*); 213 214 JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, ExecState*, JSValue); -
branches/ftlopt/Source/JavaScriptCore/runtime/JSFunction.cpp
r170564 r171605 391 391 { 392 392 JSFunction* thisObject = jsCast<JSFunction*>(object); 393 if (!thisObject->isHostOrBuiltinFunction() && (mode == IncludeDontEnumProperties)) {393 if (!thisObject->isHostOrBuiltinFunction() && shouldIncludeDontEnumProperties(mode)) { 394 394 VM& vm = exec->vm(); 395 395 // Make sure prototype has been reified. -
branches/ftlopt/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h
r165989 r171605 412 412 JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(object); 413 413 414 if ( mode == IncludeDontEnumProperties)414 if (shouldIncludeDontEnumProperties(mode)) 415 415 array.add(exec->propertyNames().length); 416 416 -
branches/ftlopt/Source/JavaScriptCore/runtime/JSObject.cpp
r170855 r171605 76 76 77 77 for (auto iter = table->begin(vm); iter != table->end(vm); ++iter) { 78 if ((!(iter->attributes() & DontEnum) || (mode == IncludeDontEnumProperties)) && !((iter->attributes() & BuiltinOrFunction) && didReify))78 if ((!(iter->attributes() & DontEnum) || shouldIncludeDontEnumProperties(mode)) && !((iter->attributes() & BuiltinOrFunction) && didReify)) 79 79 propertyNames.add(iter.key()); 80 80 } … … 1285 1285 } 1286 1286 1287 bool JSObject::hasOwnProperty(ExecState* exec, unsigned propertyName) const 1288 { 1289 PropertySlot slot(this); 1290 return const_cast<JSObject*>(this)->methodTable(exec->vm())->getOwnPropertySlotByIndex(const_cast<JSObject*>(this), exec, propertyName, slot); 1291 } 1292 1287 1293 bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) 1288 1294 { … … 1465 1471 void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 1466 1472 { 1473 if (!shouldIncludeJSObjectPropertyNames(mode)) { 1474 // We still have to get non-indexed properties from any subclasses of JSObject that have them. 1475 object->methodTable(exec->vm())->getOwnNonIndexPropertyNames(object, exec, propertyNames, mode); 1476 return; 1477 } 1478 1467 1479 // Add numeric properties first. That appears to be the accepted convention. 1468 1480 // FIXME: Filling PropertyNameArray with an identifier for every integer … … 1481 1493 if (!butterfly->contiguous()[i]) 1482 1494 continue; 1483 propertyNames.add( Identifier::from(exec, i));1495 propertyNames.add(i); 1484 1496 } 1485 1497 break; … … 1493 1505 if (value != value) 1494 1506 continue; 1495 propertyNames.add( Identifier::from(exec, i));1507 propertyNames.add(i); 1496 1508 } 1497 1509 break; … … 1504 1516 for (unsigned i = 0; i < usedVectorLength; ++i) { 1505 1517 if (storage->m_vector[i]) 1506 propertyNames.add( Identifier::from(exec, i));1518 propertyNames.add(i); 1507 1519 } 1508 1520 … … 1513 1525 SparseArrayValueMap::const_iterator end = map->end(); 1514 1526 for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) { 1515 if ( mode == IncludeDontEnumProperties|| !(it->value.attributes & DontEnum))1527 if (shouldIncludeDontEnumProperties(mode) || !(it->value.attributes & DontEnum)) 1516 1528 keys.uncheckedAppend(static_cast<unsigned>(it->key)); 1517 1529 } … … 1519 1531 std::sort(keys.begin(), keys.end()); 1520 1532 for (unsigned i = 0; i < keys.size(); ++i) 1521 propertyNames.add( Identifier::from(exec, keys[i]));1533 propertyNames.add(keys[i]); 1522 1534 } 1523 1535 break; … … 1527 1539 RELEASE_ASSERT_NOT_REACHED(); 1528 1540 } 1529 1541 1530 1542 object->methodTable(exec->vm())->getOwnNonIndexPropertyNames(object, exec, propertyNames, mode); 1531 1543 } … … 1535 1547 getClassPropertyNames(exec, object->classInfo(), propertyNames, mode, object->staticFunctionsReified()); 1536 1548 1549 if (!shouldIncludeJSObjectPropertyNames(mode)) 1550 return; 1551 1537 1552 VM& vm = exec->vm(); 1538 bool canCachePropertiesFromStructure = !propertyNames.size();1539 1553 object->structure(vm)->getPropertyNamesFromStructure(vm, propertyNames, mode); 1540 1541 if (canCachePropertiesFromStructure)1542 propertyNames.setNumCacheableSlotsForObject(object, propertyNames.size());1543 1554 } 1544 1555 … … 2653 2664 } 2654 2665 2666 uint32_t JSObject::getEnumerableLength(ExecState* exec, JSObject* object) 2667 { 2668 VM& vm = exec->vm(); 2669 Structure* structure = object->structure(vm); 2670 if (structure->holesMustForwardToPrototype(vm)) 2671 return 0; 2672 switch (object->indexingType()) { 2673 case ALL_BLANK_INDEXING_TYPES: 2674 case ALL_UNDECIDED_INDEXING_TYPES: 2675 return 0; 2676 2677 case ALL_INT32_INDEXING_TYPES: 2678 case ALL_CONTIGUOUS_INDEXING_TYPES: { 2679 Butterfly* butterfly = object->butterfly(); 2680 unsigned usedLength = butterfly->publicLength(); 2681 for (unsigned i = 0; i < usedLength; ++i) { 2682 if (!butterfly->contiguous()[i]) 2683 return 0; 2684 } 2685 return usedLength; 2686 } 2687 2688 case ALL_DOUBLE_INDEXING_TYPES: { 2689 Butterfly* butterfly = object->butterfly(); 2690 unsigned usedLength = butterfly->publicLength(); 2691 for (unsigned i = 0; i < usedLength; ++i) { 2692 double value = butterfly->contiguousDouble()[i]; 2693 if (value != value) 2694 return 0; 2695 } 2696 return usedLength; 2697 } 2698 2699 case ALL_ARRAY_STORAGE_INDEXING_TYPES: { 2700 ArrayStorage* storage = object->m_butterfly->arrayStorage(); 2701 if (storage->m_sparseMap.get()) 2702 return 0; 2703 2704 unsigned usedVectorLength = std::min(storage->length(), storage->vectorLength()); 2705 for (unsigned i = 0; i < usedVectorLength; ++i) { 2706 if (!storage->m_vector[i]) 2707 return 0; 2708 } 2709 return usedVectorLength; 2710 } 2711 2712 default: 2713 RELEASE_ASSERT_NOT_REACHED(); 2714 return 0; 2715 } 2716 } 2717 2718 void JSObject::getStructurePropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 2719 { 2720 VM& vm = exec->vm(); 2721 object->structure(vm)->getPropertyNamesFromStructure(vm, propertyNames, mode); 2722 } 2723 2724 void JSObject::getGenericPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 2725 { 2726 VM& vm = exec->vm(); 2727 object->methodTable(vm)->getOwnPropertyNames(object, exec, propertyNames, modeThatSkipsJSObject(mode)); 2728 2729 if (object->prototype().isNull()) 2730 return; 2731 2732 JSObject* prototype = asObject(object->prototype()); 2733 while (true) { 2734 if (prototype->structure(vm)->typeInfo().overridesGetPropertyNames()) { 2735 prototype->methodTable(vm)->getPropertyNames(prototype, exec, propertyNames, mode); 2736 break; 2737 } 2738 prototype->methodTable(vm)->getOwnPropertyNames(prototype, exec, propertyNames, mode); 2739 JSValue nextProto = prototype->prototype(); 2740 if (nextProto.isNull()) 2741 break; 2742 prototype = asObject(nextProto); 2743 } 2744 } 2745 2746 2655 2747 } // namespace JSC -
branches/ftlopt/Source/JavaScriptCore/runtime/JSObject.h
r170855 r171605 463 463 JS_EXPORT_PRIVATE bool hasProperty(ExecState*, unsigned propertyName) const; 464 464 bool hasOwnProperty(ExecState*, PropertyName) const; 465 bool hasOwnProperty(ExecState*, unsigned) const; 465 466 466 467 JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName); … … 475 476 JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 476 477 JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 478 479 JS_EXPORT_PRIVATE static uint32_t getEnumerableLength(ExecState*, JSObject*); 480 JS_EXPORT_PRIVATE static void getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 481 JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 477 482 478 483 JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const; -
branches/ftlopt/Source/JavaScriptCore/runtime/JSProxy.cpp
r164764 r171605 119 119 } 120 120 121 uint32_t JSProxy::getEnumerableLength(ExecState* exec, JSObject* object) 122 { 123 JSProxy* thisObject = jsCast<JSProxy*>(object); 124 return thisObject->target()->methodTable(exec->vm())->getEnumerableLength(exec, thisObject->target()); 125 } 126 127 void JSProxy::getStructurePropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 128 { 129 JSProxy* thisObject = jsCast<JSProxy*>(object); 130 thisObject->target()->methodTable(exec->vm())->getStructurePropertyNames(thisObject->target(), exec, propertyNames, mode); 131 } 132 133 void JSProxy::getGenericPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 134 { 135 JSProxy* thisObject = jsCast<JSProxy*>(object); 136 thisObject->target()->methodTable(exec->vm())->getGenericPropertyNames(thisObject->target(), exec, propertyNames, mode); 137 } 138 121 139 void JSProxy::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 122 140 { -
branches/ftlopt/Source/JavaScriptCore/runtime/JSProxy.h
r167963 r171605 84 84 JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 85 85 JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 86 JS_EXPORT_PRIVATE static uint32_t getEnumerableLength(ExecState*, JSObject*); 87 JS_EXPORT_PRIVATE static void getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 88 JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 86 89 JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); 87 90 -
branches/ftlopt/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp
r165676 r171605 67 67 if (it->key->isEmptyUnique()) 68 68 continue; 69 if (!(it->value.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))69 if (!(it->value.getAttributes() & DontEnum) || shouldIncludeDontEnumProperties(mode)) 70 70 propertyNames.add(Identifier(exec, it->key.get())); 71 71 } -
branches/ftlopt/Source/JavaScriptCore/runtime/PropertyNameArray.cpp
r165999 r171605 24 24 #include "JSCInlines.h" 25 25 #include "JSObject.h" 26 #include "JSPropertyNameEnumerator.h" 26 27 #include "Structure.h" 27 28 #include "StructureChain.h" … … 29 30 namespace JSC { 30 31 31 static const size_t setThreshold = 20;32 33 32 void PropertyNameArray::add(StringImpl* identifier) 34 33 { 35 34 ASSERT(!identifier || identifier == StringImpl::empty() || identifier->isAtomic()); 35 if (!ASSERT_DISABLED) { 36 uint32_t index = PropertyName(Identifier(m_vm, identifier)).asIndex(); 37 ASSERT_UNUSED(index, index == PropertyName::NotAnIndex || index >= m_previouslyEnumeratedLength); 38 } 36 39 37 size_t size = m_data->propertyNameVector().size(); 38 if (size < setThreshold) { 39 for (size_t i = 0; i < size; ++i) { 40 if (identifier == m_data->propertyNameVector()[i].impl()) 41 return; 42 } 43 } else { 44 if (m_set.isEmpty()) { 45 for (size_t i = 0; i < size; ++i) 46 m_set.add(m_data->propertyNameVector()[i].impl()); 47 } 48 if (!m_set.add(identifier).isNewEntry) 49 return; 50 } 40 if (m_alternateSet && m_alternateSet->contains(identifier)) 41 return; 42 43 if (!m_set->add(identifier).isNewEntry) 44 return; 51 45 52 46 addKnownUnique(identifier); 53 47 } 54 48 49 void PropertyNameArray::setPreviouslyEnumeratedProperties(const JSPropertyNameEnumerator* enumerator) 50 { 51 m_alternateSet = enumerator->identifierSet(); 52 } 53 55 54 } // namespace JSC -
branches/ftlopt/Source/JavaScriptCore/runtime/PropertyNameArray.h
r157653 r171605 29 29 namespace JSC { 30 30 31 class JSPropertyNameEnumerator; 31 32 class Structure; 32 33 class StructureChain; 34 35 class RefCountedIdentifierSet : public RefCounted<RefCountedIdentifierSet> { 36 public: 37 typedef HashSet<StringImpl*, PtrHash<StringImpl*>> Set; 38 39 bool contains(StringImpl* impl) const { return m_set.contains(impl); } 40 size_t size() const { return m_set.size(); } 41 Set::AddResult add(StringImpl* impl) { return m_set.add(impl); } 42 43 private: 44 Set m_set; 45 }; 33 46 34 47 // FIXME: Rename to PropertyNameArray. … … 54 67 PropertyNameArray(VM* vm) 55 68 : m_data(PropertyNameArrayData::create()) 69 , m_set(adoptRef(new RefCountedIdentifierSet)) 56 70 , m_vm(vm) 57 71 , m_numCacheableSlots(0) 58 72 , m_baseObject(0) 73 , m_previouslyEnumeratedLength(0) 59 74 { 60 75 } … … 62 77 PropertyNameArray(ExecState* exec) 63 78 : m_data(PropertyNameArrayData::create()) 79 , m_set(adoptRef(new RefCountedIdentifierSet)) 64 80 , m_vm(&exec->vm()) 65 81 , m_numCacheableSlots(0) 66 82 , m_baseObject(0) 83 , m_previouslyEnumeratedLength(0) 67 84 { 68 85 } … … 70 87 VM* vm() { return m_vm; } 71 88 89 void add(uint32_t index) 90 { 91 if (index < m_previouslyEnumeratedLength) 92 return; 93 add(Identifier::from(m_vm, index)); 94 } 95 72 96 void add(const Identifier& identifier) { add(identifier.impl()); } 73 97 JS_EXPORT_PRIVATE void add(StringImpl*); 74 void addKnownUnique(StringImpl* identifier) { m_data->propertyNameVector().append(Identifier(m_vm, identifier)); } 98 void addKnownUnique(StringImpl* identifier) 99 { 100 m_set->add(identifier); 101 m_data->propertyNameVector().append(Identifier(m_vm, identifier)); 102 } 75 103 76 104 Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; } … … 81 109 PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); } 82 110 111 RefCountedIdentifierSet* identifierSet() const { return m_set.get(); } 112 83 113 // FIXME: Remove these functions. 114 bool canAddKnownUniqueForStructure() const { return !m_set->size() && (!m_alternateSet || !m_alternateSet->size()); } 84 115 typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator; 85 116 size_t size() const { return m_data->propertyNameVector().size(); } … … 101 132 } 102 133 134 void setPreviouslyEnumeratedLength(uint32_t length) { m_previouslyEnumeratedLength = length; } 135 void setPreviouslyEnumeratedProperties(const JSPropertyNameEnumerator*); 136 103 137 private: 104 typedef HashSet<StringImpl*, PtrHash<StringImpl*>> IdentifierSet;105 106 138 RefPtr<PropertyNameArrayData> m_data; 107 IdentifierSet m_set; 139 RefPtr<RefCountedIdentifierSet> m_set; 140 RefPtr<RefCountedIdentifierSet> m_alternateSet; 108 141 VM* m_vm; 109 142 size_t m_numCacheableSlots; 110 143 JSObject* m_baseObject; 144 uint32_t m_previouslyEnumeratedLength; 111 145 }; 112 146 -
branches/ftlopt/Source/JavaScriptCore/runtime/RegExpObject.cpp
r163844 r171605 110 110 void RegExpObject::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 111 111 { 112 if ( mode == IncludeDontEnumProperties)112 if (shouldIncludeDontEnumProperties(mode)) 113 113 propertyNames.add(exec->propertyNames().lastIndex); 114 114 Base::getOwnNonIndexPropertyNames(object, exec, propertyNames, mode); … … 117 117 void RegExpObject::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 118 118 { 119 if ( mode == IncludeDontEnumProperties)119 if (shouldIncludeDontEnumProperties(mode)) 120 120 propertyNames.add(exec->propertyNames().lastIndex); 121 121 Base::getPropertyNames(object, exec, propertyNames, mode); 122 } 123 124 void RegExpObject::getGenericPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 125 { 126 if (shouldIncludeDontEnumProperties(mode)) 127 propertyNames.add(exec->propertyNames().lastIndex); 128 Base::getGenericPropertyNames(object, exec, propertyNames, mode); 122 129 } 123 130 -
branches/ftlopt/Source/JavaScriptCore/runtime/RegExpObject.h
r156668 r171605 78 78 JS_EXPORT_PRIVATE void finishCreation(VM&); 79 79 80 static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | Base::StructureFlags;80 static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags; 81 81 82 82 static void visitChildren(JSCell*, SlotVisitor&); … … 85 85 JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 86 86 JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 87 JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 87 88 JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); 88 89 -
branches/ftlopt/Source/JavaScriptCore/runtime/StringObject.cpp
r163844 r171605 151 151 for (int i = 0; i < size; ++i) 152 152 propertyNames.add(Identifier::from(exec, i)); 153 if ( mode == IncludeDontEnumProperties)153 if (shouldIncludeDontEnumProperties(mode)) 154 154 propertyNames.add(exec->propertyNames().length); 155 155 return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); -
branches/ftlopt/Source/JavaScriptCore/runtime/Structure.cpp
r171510 r171605 31 31 #include "JSCInlines.h" 32 32 #include "JSObject.h" 33 #include "JSPropertyName Iterator.h"33 #include "JSPropertyNameEnumerator.h" 34 34 #include "Lookup.h" 35 35 #include "PropertyMapHashTable.h" … … 957 957 return; 958 958 959 bool knownUnique = !propertyNames.size();959 bool knownUnique = propertyNames.canAddKnownUniqueForStructure(); 960 960 961 961 PropertyTable::iterator end = propertyTable()->end(); 962 962 for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) { 963 963 ASSERT(hasNonEnumerableProperties() || !(iter->attributes & DontEnum)); 964 if (!iter->key->isEmptyUnique() && (!(iter->attributes & DontEnum) || mode == IncludeDontEnumProperties)) {964 if (!iter->key->isEmptyUnique() && (!(iter->attributes & DontEnum) || shouldIncludeDontEnumProperties(mode))) { 965 965 if (knownUnique) 966 966 propertyNames.addKnownUnique(iter->key); … … 1261 1261 } 1262 1262 1263 void Structure::setCachedStructurePropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator) 1264 { 1265 ASSERT(!isDictionary()); 1266 if (!hasRareData()) 1267 allocateRareData(vm); 1268 rareData()->setCachedStructurePropertyNameEnumerator(vm, enumerator); 1269 } 1270 1271 JSPropertyNameEnumerator* Structure::cachedStructurePropertyNameEnumerator() const 1272 { 1273 if (!hasRareData()) 1274 return nullptr; 1275 return rareData()->cachedStructurePropertyNameEnumerator(); 1276 } 1277 1278 void Structure::setCachedGenericPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator) 1279 { 1280 ASSERT(!isDictionary()); 1281 if (!hasRareData()) 1282 allocateRareData(vm); 1283 rareData()->setCachedGenericPropertyNameEnumerator(vm, enumerator); 1284 } 1285 1286 JSPropertyNameEnumerator* Structure::cachedGenericPropertyNameEnumerator() const 1287 { 1288 if (!hasRareData()) 1289 return nullptr; 1290 return rareData()->cachedGenericPropertyNameEnumerator(); 1291 } 1292 1293 bool Structure::canCacheStructurePropertyNameEnumerator() const 1294 { 1295 if (isDictionary()) 1296 return false; 1297 return true; 1298 } 1299 1300 bool Structure::canCacheGenericPropertyNameEnumerator() const 1301 { 1302 if (!canCacheStructurePropertyNameEnumerator()) 1303 return false; 1304 1305 if (hasIndexedProperties(indexingType())) 1306 return false; 1307 1308 StructureChain* structureChain = m_cachedPrototypeChain.get(); 1309 ASSERT(structureChain); 1310 WriteBarrier<Structure>* structure = structureChain->head(); 1311 while (true) { 1312 if (!structure->get()) 1313 break; 1314 if (structure->get()->typeInfo().overridesGetPropertyNames()) 1315 return false; 1316 structure++; 1317 } 1318 1319 return true; 1320 } 1321 1322 bool Structure::canAccessPropertiesQuickly() const 1323 { 1324 if (hasNonEnumerableProperties()) 1325 return false; 1326 if (hasGetterSetterProperties()) 1327 return false; 1328 if (isUncacheableDictionary()) 1329 return false; 1330 return true; 1331 } 1332 1263 1333 } // namespace JSC -
branches/ftlopt/Source/JavaScriptCore/runtime/Structure.h
r171510 r171605 284 284 void setEnumerationCache(VM&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h. 285 285 JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h. 286 287 void setCachedStructurePropertyNameEnumerator(VM&, JSPropertyNameEnumerator*); 288 void setCachedGenericPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*); 289 JSPropertyNameEnumerator* cachedStructurePropertyNameEnumerator() const; 290 JSPropertyNameEnumerator* cachedGenericPropertyNameEnumerator() const; 291 bool canCacheStructurePropertyNameEnumerator() const; 292 bool canCacheGenericPropertyNameEnumerator() const; 293 bool canAccessPropertiesQuickly() const; 294 286 295 void getPropertyNamesFromStructure(VM&, PropertyNameArray&, EnumerationMode); 287 296 -
branches/ftlopt/Source/JavaScriptCore/runtime/StructureRareData.cpp
r170855 r171605 27 27 #include "StructureRareData.h" 28 28 29 #include "JSPropertyNameEnumerator.h" 29 30 #include "JSPropertyNameIterator.h" 30 31 #include "JSString.h" … … 69 70 visitor.append(&thisObject->m_objectToStringValue); 70 71 visitor.append(&thisObject->m_enumerationCache); 72 visitor.append(&thisObject->m_cachedStructurePropertyNameEnumerator); 73 visitor.append(&thisObject->m_cachedGenericPropertyNameEnumerator); 74 } 75 76 JSPropertyNameEnumerator* StructureRareData::cachedStructurePropertyNameEnumerator() const 77 { 78 return m_cachedStructurePropertyNameEnumerator.get(); 79 } 80 81 void StructureRareData::setCachedStructurePropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator) 82 { 83 m_cachedStructurePropertyNameEnumerator.set(vm, this, enumerator); 84 } 85 86 JSPropertyNameEnumerator* StructureRareData::cachedGenericPropertyNameEnumerator() const 87 { 88 return m_cachedGenericPropertyNameEnumerator.get(); 89 } 90 91 void StructureRareData::setCachedGenericPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator) 92 { 93 m_cachedGenericPropertyNameEnumerator.set(vm, this, enumerator); 71 94 } 72 95 -
branches/ftlopt/Source/JavaScriptCore/runtime/StructureRareData.h
r170855 r171605 34 34 namespace JSC { 35 35 36 class JSPropertyNameEnumerator; 36 37 class JSPropertyNameIterator; 37 38 class Structure; … … 62 63 DECLARE_EXPORT_INFO; 63 64 65 JSPropertyNameEnumerator* cachedStructurePropertyNameEnumerator() const; 66 JSPropertyNameEnumerator* cachedGenericPropertyNameEnumerator() const; 67 void setCachedStructurePropertyNameEnumerator(VM&, JSPropertyNameEnumerator*); 68 void setCachedGenericPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*); 69 64 70 private: 65 71 friend class Structure; … … 72 78 WriteBarrier<JSString> m_objectToStringValue; 73 79 WriteBarrier<JSPropertyNameIterator> m_enumerationCache; 80 WriteBarrier<JSPropertyNameEnumerator> m_cachedStructurePropertyNameEnumerator; 81 WriteBarrier<JSPropertyNameEnumerator> m_cachedGenericPropertyNameEnumerator; 74 82 75 83 typedef HashMap<PropertyOffset, RefPtr<WatchpointSet>, WTF::IntHash<PropertyOffset>, WTF::UnsignedWithZeroKeyHashTraits<PropertyOffset>> PropertyWatchpointMap; -
branches/ftlopt/Source/JavaScriptCore/runtime/VM.cpp
r171510 r171605 65 65 #include "JSPromiseDeferred.h" 66 66 #include "JSPromiseReaction.h" 67 #include "JSPropertyNameEnumerator.h" 67 68 #include "JSPropertyNameIterator.h" 68 69 #include "JSWithScope.h" … … 259 260 notAnObjectStructure.set(*this, JSNotAnObject::createStructure(*this, 0, jsNull())); 260 261 propertyNameIteratorStructure.set(*this, JSPropertyNameIterator::createStructure(*this, 0, jsNull())); 262 propertyNameEnumeratorStructure.set(*this, JSPropertyNameEnumerator::createStructure(*this, 0, jsNull())); 261 263 getterSetterStructure.set(*this, GetterSetter::createStructure(*this, 0, jsNull())); 262 264 apiWrapperStructure.set(*this, JSAPIValueWrapper::createStructure(*this, 0, jsNull())); -
branches/ftlopt/Source/JavaScriptCore/runtime/VM.h
r171510 r171605 267 267 Strong<Structure> notAnObjectStructure; 268 268 Strong<Structure> propertyNameIteratorStructure; 269 Strong<Structure> propertyNameEnumeratorStructure; 269 270 Strong<Structure> getterSetterStructure; 270 271 Strong<Structure> apiWrapperStructure; … … 292 293 #endif 293 294 Strong<JSCell> iterationTerminator; 295 Strong<JSCell> emptyPropertyNameEnumerator; 294 296 295 297 AtomicStringTable* m_atomicStringTable; -
branches/ftlopt/Source/WebCore/ChangeLog
r170680 r171605 1 2014-07-23 Mark Hahnenberg <[email protected]> 2 3 Refactor our current implementation of for-in 4 https://bugs.webkit.org/show_bug.cgi?id=134142 5 6 Reviewed by Filip Pizlo. 7 8 No new tests. 9 10 This patch splits for-in loops into three distinct parts: 11 12 - Iterating over the indexed properties in the base object. 13 - Iterating over the Structure properties in the base object. 14 - Iterating over any other enumerable properties for that object and any objects in the prototype chain. 15 16 It does this by emitting these explicit loops in bytecode, using a new set of bytecodes to 17 support the various operations required for each loop. 18 19 * bindings/js/JSDOMWindowCustom.cpp: 20 (WebCore::JSDOMWindow::getEnumerableLength): 21 (WebCore::JSDOMWindow::getStructurePropertyNames): 22 (WebCore::JSDOMWindow::getGenericPropertyNames): 23 * bindings/scripts/CodeGeneratorJS.pm: 24 (GenerateHeader): 25 * bridge/runtime_array.cpp: 26 (JSC::RuntimeArray::getOwnPropertyNames): 27 1 28 2014-07-01 Mark Lam <[email protected]> 2 29 -
branches/ftlopt/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
r167794 r171605 382 382 } 383 383 384 uint32_t JSDOMWindow::getEnumerableLength(ExecState* exec, JSObject* object) 385 { 386 JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); 387 // Only allow the window to enumerated by frames in the same origin. 388 if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl())) 389 return 0; 390 return Base::getEnumerableLength(exec, thisObject); 391 } 392 393 void JSDOMWindow::getStructurePropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 394 { 395 JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); 396 // Only allow the window to enumerated by frames in the same origin. 397 if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl())) 398 return; 399 Base::getStructurePropertyNames(thisObject, exec, propertyNames, mode); 400 } 401 402 void JSDOMWindow::getGenericPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 403 { 404 JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(object); 405 // Only allow the window to enumerated by frames in the same origin. 406 if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->impl())) 407 return; 408 Base::getGenericPropertyNames(thisObject, exec, propertyNames, mode); 409 } 410 384 411 void JSDOMWindow::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 385 412 { -
branches/ftlopt/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
r170564 r171605 973 973 if ($interfaceName eq "DOMWindow") { 974 974 push(@headerContent, " static void getPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);\n"); 975 push(@headerContent, " static void getGenericPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);\n"); 976 push(@headerContent, " static void getStructurePropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);\n"); 977 push(@headerContent, " static uint32_t getEnumerableLength(JSC::ExecState*, JSC::JSObject*);\n"); 975 978 $structureFlags{"JSC::OverridesGetPropertyNames"} = 1; 976 979 } -
branches/ftlopt/Source/WebCore/bridge/runtime_array.cpp
r165676 r171605 82 82 propertyNames.add(Identifier::from(exec, i)); 83 83 84 if ( mode == IncludeDontEnumProperties)84 if (shouldIncludeDontEnumProperties(mode)) 85 85 propertyNames.add(exec->propertyNames().length); 86 86 -
branches/ftlopt/Source/WebKit2/ChangeLog
r168513 r171605 1 2014-07-23 Mark Hahnenberg <[email protected]> 2 3 Refactor our current implementation of for-in 4 https://bugs.webkit.org/show_bug.cgi?id=134142 5 6 Reviewed by Filip Pizlo. 7 8 * WebProcess/Plugins/Netscape/JSNPObject.cpp: 9 (WebKit::JSNPObject::invalidate): Fixed an invalid ASSERT that was crashing in debug builds. 10 1 11 2014-05-08 Simon Fraser <[email protected]> 2 12 -
branches/ftlopt/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp
r166091 r171605 91 91 { 92 92 ASSERT(m_npObject); 93 ASSERT_GC_OBJECT_INHERITS(this, info());94 93 95 94 releaseNPObject(m_npObject);
Note:
See TracChangeset
for help on using the changeset viewer.