Changeset 206065 in webkit
- Timestamp:
- Sep 16, 2016 11:32:50 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 48 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r206064 r206065 1 2016-09-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [DFG] Introduce IsCellWithType node and unify IsJSArray, IsRegExpObject and newly added IsProxyObject 4 https://bugs.webkit.org/show_bug.cgi?id=162000 5 6 Reviewed by Filip Pizlo. 7 8 * microbenchmarks/is-array-for-array.js: Added. 9 (isArray): 10 * microbenchmarks/is-array-for-mixed-case.js: Added. 11 (isArray): 12 * microbenchmarks/is-array-for-non-array-object.js: Added. 13 (isArray): 14 * microbenchmarks/is-array-for-proxy.js: Added. 15 (isArray): 16 (isArray.proxy.throw.new.Error.isArray): 17 (isArray.proxy.throw.new.Error): 18 1 19 2016-09-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 20 -
trunk/Source/JavaScriptCore/ChangeLog
r206047 r206065 1 2016-09-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [DFG] Introduce IsCellWithType node and unify IsJSArray, IsRegExpObject and newly added IsProxyObject 4 https://bugs.webkit.org/show_bug.cgi?id=162000 5 6 Reviewed by Filip Pizlo. 7 8 Sampling profiler tells that ES6SampleBench/Basic frequently calls Array.isArray(). This function is introduced in 9 ES5 and it is well-used to distinguish Array from the other objects. Moreover, this function is used in Array.prototype.xxx 10 methods as @isArray. So it's worth optimizing. 11 12 The difference between Array.isArray and @isJSArray is that Array.isArray need to consider about ProxyObject while 13 @isJSArray builtin intrinsic does not. So in this patch, we leverage the existing @isJSArray to implement Array.isArray. 14 Array.isArray is written in builtin JS code using @isJSArray and newly added @isProxyObject(). That allow us to inline 15 Array.isArray() code and the inlined code uses existing DFG nodes well. 16 17 Another problem is RuntimeArray and ArrayPrototype. They inherit JSArray and their JSType is ObjectType. But Array.isArray need 18 to return true for those types. While optimizing type checking in generic way by type display is nice, RuntimeArray and 19 ArrayPrototype are a bit tricky and it is super rare that these functions are passed to Array.isArray(). So instead of introducing 20 type display in this patch, we just introduce a new JSType, DerivedArrayType and use it in the above 2 use classes. Since 21 Array.isArray is specially handled in the spec (while we don't have any Date.isDate() like functions, only Array.isArray 22 is specified in the spec because we frequently want to distinguish Arrays from other Objects), optimizing Array.isArray specially 23 by introducing special DerivedArrayType is reasonable. 24 25 In LLInt level, we add a new opcode, op_is_proxy_object and op_is_derived_array. This works similar to op_is_jsarray. 26 And we also perform LLInt code cleanup by introducing a macro isCellWithType. 27 28 In baseline, we perform some clean up for op_is_proxy_object etc. Now duplicate code is reduced. 29 30 In DFG, we unify IsJSArray, IsRegExpObject, IsProxyObject, and IsDerivedArray into one IsCellWithType node. And we clean up 31 some AI code related to IsJSArray and IsRegExpObject since SpeculatedType now recognizes ProxyObject. IsJSArray and IsRegExpObject 32 does not do anything special for proxy objects. 33 34 The above change simplify things to create a new IsXXX DFG handling and paves the way for optimizing @isMap & @isSet in DFG. 35 Furthermore, introducing @isProxyObject() is nice for the first step to optimize ProxyObject handling. 36 37 Here is microbenchmark result. We can see stable performance improvement (Even if we use Proxies!). 38 39 baseline patched 40 41 is-array-for-array 2.5156+-0.0288 ^ 2.0668+-0.0285 ^ definitely 1.2171x faster 42 is-array-for-mixed-case 4.7787+-0.0755 ^ 4.4722+-0.0789 ^ definitely 1.0686x faster 43 is-array-for-non-array-object 2.3596+-0.0368 ^ 1.8178+-0.0262 ^ definitely 1.2980x faster 44 is-array-for-proxy 4.0469+-0.0437 ^ 3.3845+-0.0404 ^ definitely 1.1957x faster 45 46 And ES6SampleBench/Basic reports 5.2% perf improvement. And now sampling result in ES6SampleBench/Basic does not pose Array.isArray. 47 48 Benchmark First Iteration Worst 2% Steady State 49 baseline:Basic 28.59 ms +- 1.03 ms 15.08 ms +- 0.28 ms 1656.96 ms +- 18.02 ms 50 patched:Basic 27.82 ms +- 0.44 ms 14.59 ms +- 0.16 ms 1574.65 ms +- 8.44 ms 51 52 * builtins/ArrayConstructor.js: 53 (isArray): 54 (from): Deleted. 55 * builtins/BuiltinNames.h: 56 * bytecode/BytecodeIntrinsicRegistry.h: 57 * bytecode/BytecodeList.json: 58 * bytecode/BytecodeUseDef.h: 59 (JSC::computeUsesForBytecodeOffset): 60 (JSC::computeDefsForBytecodeOffset): 61 * bytecode/CodeBlock.cpp: 62 (JSC::CodeBlock::dumpBytecode): 63 * bytecode/SpeculatedType.cpp: 64 (JSC::dumpSpeculation): 65 (JSC::speculationFromClassInfo): 66 (JSC::speculationFromStructure): 67 * bytecode/SpeculatedType.h: 68 (JSC::isProxyObjectSpeculation): 69 (JSC::isDerivedArraySpeculation): 70 * bytecompiler/BytecodeGenerator.h: 71 (JSC::BytecodeGenerator::emitIsProxyObject): 72 (JSC::BytecodeGenerator::emitIsDerivedArray): 73 (JSC::BytecodeGenerator::emitIsJSArray): Deleted. 74 * bytecompiler/NodesCodegen.cpp: 75 (JSC::BytecodeIntrinsicNode::emit_intrinsic_isProxyObject): 76 (JSC::BytecodeIntrinsicNode::emit_intrinsic_isDerivedArray): 77 * dfg/DFGAbstractInterpreterInlines.h: 78 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 79 * dfg/DFGByteCodeParser.cpp: 80 (JSC::DFG::ByteCodeParser::handleIntrinsicCall): 81 (JSC::DFG::ByteCodeParser::parseBlock): 82 * dfg/DFGCapabilities.cpp: 83 (JSC::DFG::capabilityLevel): 84 * dfg/DFGClobberize.h: 85 (JSC::DFG::clobberize): 86 * dfg/DFGDoesGC.cpp: 87 (JSC::DFG::doesGC): 88 * dfg/DFGFixupPhase.cpp: 89 (JSC::DFG::FixupPhase::fixupNode): 90 (JSC::DFG::FixupPhase::fixupIsCellWithType): 91 * dfg/DFGGraph.cpp: 92 (JSC::DFG::Graph::dump): 93 * dfg/DFGNode.h: 94 (JSC::DFG::Node::hasQueriedType): 95 (JSC::DFG::Node::queriedType): 96 (JSC::DFG::Node::hasSpeculatedTypeForQuery): 97 (JSC::DFG::Node::speculatedTypeForQuery): 98 (JSC::DFG::Node::shouldSpeculateProxyObject): 99 (JSC::DFG::Node::shouldSpeculateDerivedArray): 100 (JSC::DFG::Node::loadVarargsData): Deleted. 101 (JSC::DFG::Node::shouldSpeculateArray): Deleted. 102 * dfg/DFGNodeType.h: 103 * dfg/DFGPredictionPropagationPhase.cpp: 104 * dfg/DFGSafeToExecute.h: 105 (JSC::DFG::SafeToExecuteEdge::operator()): 106 (JSC::DFG::safeToExecute): 107 * dfg/DFGSpeculativeJIT.cpp: 108 (JSC::DFG::SpeculativeJIT::compileIsCellWithType): 109 (JSC::DFG::SpeculativeJIT::speculateProxyObject): 110 (JSC::DFG::SpeculativeJIT::speculateDerivedArray): 111 (JSC::DFG::SpeculativeJIT::speculate): 112 (JSC::DFG::SpeculativeJIT::compileIsJSArray): Deleted. 113 (JSC::DFG::SpeculativeJIT::compileIsRegExpObject): Deleted. 114 * dfg/DFGSpeculativeJIT.h: 115 * dfg/DFGSpeculativeJIT32_64.cpp: 116 (JSC::DFG::SpeculativeJIT::compile): 117 * dfg/DFGSpeculativeJIT64.cpp: 118 (JSC::DFG::SpeculativeJIT::compile): 119 * dfg/DFGUseKind.cpp: 120 (WTF::printInternal): 121 * dfg/DFGUseKind.h: 122 (JSC::DFG::typeFilterFor): 123 (JSC::DFG::isCell): 124 * ftl/FTLCapabilities.cpp: 125 (JSC::FTL::canCompile): 126 * ftl/FTLLowerDFGToB3.cpp: 127 (JSC::FTL::DFG::LowerDFGToB3::compileNode): 128 (JSC::FTL::DFG::LowerDFGToB3::compileIsCellWithType): 129 (JSC::FTL::DFG::LowerDFGToB3::speculate): 130 (JSC::FTL::DFG::LowerDFGToB3::isCellWithType): 131 (JSC::FTL::DFG::LowerDFGToB3::speculateProxyObject): 132 (JSC::FTL::DFG::LowerDFGToB3::speculateDerivedArray): 133 (JSC::FTL::DFG::LowerDFGToB3::compileIsJSArray): Deleted. 134 (JSC::FTL::DFG::LowerDFGToB3::compileIsRegExpObject): Deleted. 135 (JSC::FTL::DFG::LowerDFGToB3::isArray): Deleted. 136 (JSC::FTL::DFG::LowerDFGToB3::isRegExpObject): Deleted. 137 * jit/JIT.cpp: 138 (JSC::JIT::privateCompileMainPass): 139 * jit/JIT.h: 140 * jit/JITOpcodes.cpp: 141 (JSC::JIT::emitIsCellWithType): 142 (JSC::JIT::emit_op_is_string): 143 (JSC::JIT::emit_op_is_jsarray): 144 (JSC::JIT::emit_op_is_proxy_object): 145 (JSC::JIT::emit_op_is_derived_array): 146 * jit/JITOpcodes32_64.cpp: 147 (JSC::JIT::emitIsCellWithType): 148 (JSC::JIT::emit_op_is_string): 149 (JSC::JIT::emit_op_is_jsarray): 150 (JSC::JIT::emit_op_is_proxy_object): 151 (JSC::JIT::emit_op_is_derived_array): 152 * jsc.cpp: 153 (WTF::RuntimeArray::createStructure): 154 * llint/LLIntData.cpp: 155 (JSC::LLInt::Data::performAssertions): 156 * llint/LowLevelInterpreter.asm: 157 * llint/LowLevelInterpreter32_64.asm: 158 * llint/LowLevelInterpreter64.asm: 159 * runtime/ArrayConstructor.cpp: 160 (JSC::ArrayConstructor::finishCreation): 161 (JSC::isArraySlowInline): 162 (JSC::isArraySlow): 163 (JSC::arrayConstructorPrivateFuncIsArraySlow): 164 (JSC::arrayConstructorIsArray): Deleted. 165 * runtime/ArrayConstructor.h: 166 (JSC::isArray): 167 * runtime/ArrayPrototype.h: 168 (JSC::ArrayPrototype::createStructure): 169 * runtime/JSArray.h: 170 (JSC::JSArray::finishCreation): 171 * runtime/JSGlobalObject.cpp: 172 (JSC::JSGlobalObject::init): 173 * runtime/JSType.h: 174 1 175 2016-09-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 176 -
trunk/Source/JavaScriptCore/builtins/ArrayConstructor.js
r204597 r206065 103 103 return result; 104 104 } 105 106 function isArray(array) 107 { 108 "use strict"; 109 110 if (@isJSArray(array) || @isDerivedArray(array)) 111 return true; 112 if (!@isProxyObject(array)) 113 return false; 114 return @isArraySlow(array); 115 } -
trunk/Source/JavaScriptCore/builtins/BuiltinNames.h
r205848 r206065 127 127 macro(hasInstanceBoundFunction) \ 128 128 macro(instanceOf) \ 129 macro(isArray ) \129 macro(isArraySlow) \ 130 130 macro(isArrayConstructor) \ 131 131 macro(isConstructor) \ -
trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
r205278 r206065 44 44 macro(isObject) \ 45 45 macro(isJSArray) \ 46 macro(isProxyObject) \ 47 macro(isDerivedArray) \ 46 48 macro(tailCallForwardArguments) \ 47 49 macro(tryGetById) \ -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.json
r205321 r206065 58 58 { "name" : "op_is_string", "length" : 3 }, 59 59 { "name" : "op_is_jsarray", "length" : 3 }, 60 { "name" : "op_is_proxy_object", "length" : 3 }, 60 61 { "name" : "op_is_object", "length" : 3 }, 61 62 { "name" : "op_is_object_or_null", "length" : 3 }, 62 63 { "name" : "op_is_function", "length" : 3 }, 64 { "name" : "op_is_derived_array", "length" : 3 }, 63 65 { "name" : "op_in", "length" : 4 }, 64 66 { "name" : "op_get_array_length", "length" : 9 }, -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r205462 r206065 166 166 case op_is_string: 167 167 case op_is_jsarray: 168 case op_is_proxy_object: 168 169 case op_is_object: 169 170 case op_is_object_or_null: 170 171 case op_is_function: 172 case op_is_derived_array: 171 173 case op_to_number: 172 174 case op_to_string: … … 399 401 case op_is_string: 400 402 case op_is_jsarray: 403 case op_is_proxy_object: 401 404 case op_is_object: 402 405 case op_is_object_or_null: 403 406 case op_is_function: 407 case op_is_derived_array: 404 408 case op_in: 405 409 case op_to_number: -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r205794 r206065 1111 1111 break; 1112 1112 } 1113 case op_is_proxy_object: { 1114 printUnaryOp(out, exec, location, it, "is_proxy_object"); 1115 break; 1116 } 1113 1117 case op_is_object: { 1114 1118 printUnaryOp(out, exec, location, it, "is_object"); … … 1121 1125 case op_is_function: { 1122 1126 printUnaryOp(out, exec, location, it, "is_function"); 1127 break; 1128 } 1129 case op_is_derived_array: { 1130 printUnaryOp(out, exec, location, it, "is_derived_array"); 1123 1131 break; 1124 1132 } -
trunk/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
r205520 r206065 36 36 #include "JSMap.h" 37 37 #include "JSSet.h" 38 #include "ProxyObject.h" 38 39 #include "ScopedArguments.h" 39 40 #include "StringObject.h" … … 147 148 if (value & SpecRegExpObject) 148 149 myOut.print("Regexpobject"); 150 else 151 isTop = false; 152 153 if (value & SpecMapObject) 154 myOut.print("Mapobject"); 155 else 156 isTop = false; 157 158 if (value & SpecSetObject) 159 myOut.print("Setobject"); 160 else 161 isTop = false; 162 163 if (value & SpecProxyObject) 164 myOut.print("Proxyobject"); 165 else 166 isTop = false; 167 168 if (value & SpecDerivedArray) 169 myOut.print("Derivedarray"); 149 170 else 150 171 isTop = false; … … 355 376 if (classInfo == JSSet::info()) 356 377 return SpecSetObject; 378 379 if (classInfo == ProxyObject::info()) 380 return SpecProxyObject; 357 381 358 382 if (classInfo->isSubClassOf(JSFunction::info())) … … 374 398 if (structure->typeInfo().type() == SymbolType) 375 399 return SpecSymbol; 400 if (structure->typeInfo().type() == DerivedArrayType) 401 return SpecDerivedArray; 376 402 return speculationFromClassInfo(structure->classInfo()); 377 403 } -
trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h
r205520 r206065 57 57 static const SpeculatedType SpecStringObject = 1ull << 14; // It's definitely a StringObject. 58 58 static const SpeculatedType SpecRegExpObject = 1ull << 15; // It's definitely a RegExpObject (and not any subclass of RegExpObject). 59 static const SpeculatedType SpecMapObject = 1ull << 16; // It's definitely Map object (can it be a subclass? FIXME). 60 static const SpeculatedType SpecSetObject = 1ull << 17; // It's definitely s Set object (can it be a subclass? FIXME). 61 static const SpeculatedType SpecObjectOther = 1ull << 18; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction. 62 static const SpeculatedType SpecObject = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecMapObject | SpecSetObject | SpecObjectOther; // Bitmask used for testing for any kind of object prediction. 63 static const SpeculatedType SpecStringIdent = 1ull << 19; // It's definitely a JSString, and it's an identifier. 64 static const SpeculatedType SpecStringVar = 1ull << 20; // It's definitely a JSString, and it's not an identifier. 59 static const SpeculatedType SpecMapObject = 1ull << 16; // It's definitely a Map object or one of its subclasses. 60 static const SpeculatedType SpecSetObject = 1ull << 17; // It's definitely a Set object or one of its subclasses. 61 static const SpeculatedType SpecProxyObject = 1ull << 18; // It's definitely a Proxy object or one of its subclasses. 62 static const SpeculatedType SpecDerivedArray = 1ull << 19; // It's definitely a DerivedArray object. 63 static const SpeculatedType SpecObjectOther = 1ull << 20; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction. 64 static const SpeculatedType SpecObject = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecMapObject | SpecSetObject | SpecProxyObject | SpecDerivedArray | SpecObjectOther; // Bitmask used for testing for any kind of object prediction. 65 static const SpeculatedType SpecStringIdent = 1ull << 21; // It's definitely a JSString, and it's an identifier. 66 static const SpeculatedType SpecStringVar = 1ull << 22; // It's definitely a JSString, and it's not an identifier. 65 67 static const SpeculatedType SpecString = SpecStringIdent | SpecStringVar; // It's definitely a JSString. 66 static const SpeculatedType SpecSymbol = 1ull << 2 1; // It's definitely a Symbol.67 static const SpeculatedType SpecCellOther = 1ull << 2 2; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString or a Symbol. FIXME: This shouldn't be part of heap-top or bytecode-top. https://bugs.webkit.org/show_bug.cgi?id=13307868 static const SpeculatedType SpecSymbol = 1ull << 23; // It's definitely a Symbol. 69 static const SpeculatedType SpecCellOther = 1ull << 24; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString or a Symbol. FIXME: This shouldn't be part of heap-top or bytecode-top. https://bugs.webkit.org/show_bug.cgi?id=133078 68 70 static const SpeculatedType SpecCell = SpecObject | SpecString | SpecSymbol | SpecCellOther; // It's definitely a JSCell. 69 static const SpeculatedType SpecBoolInt32 = 1ull << 2 3; // It's definitely an Int32 with value 0 or 1.70 static const SpeculatedType SpecNonBoolInt32 = 1ull << 2 4; // It's definitely an Int32 with value other than 0 or 1.71 static const SpeculatedType SpecBoolInt32 = 1ull << 25; // It's definitely an Int32 with value 0 or 1. 72 static const SpeculatedType SpecNonBoolInt32 = 1ull << 26; // It's definitely an Int32 with value other than 0 or 1. 71 73 static const SpeculatedType SpecInt32Only = SpecBoolInt32 | SpecNonBoolInt32; // It's definitely an Int32. 72 static const SpeculatedType SpecInt52Only = 1ull << 2 5; // It's definitely an Int52 and we intend it to unbox it. It's also definitely not an Int32.74 static const SpeculatedType SpecInt52Only = 1ull << 27; // It's definitely an Int52 and we intend it to unbox it. It's also definitely not an Int32. 73 75 static const SpeculatedType SpecAnyInt = SpecInt32Only | SpecInt52Only; // It's something that we can do machine int arithmetic on. 74 static const SpeculatedType SpecAnyIntAsDouble = 1ull << 2 6; // It's definitely an Int52 and it's inside a double.75 static const SpeculatedType SpecNonIntAsDouble = 1ull << 2 7; // It's definitely not an Int52 but it's a real number and it's a double.76 static const SpeculatedType SpecAnyIntAsDouble = 1ull << 28; // It's definitely an Int52 and it's inside a double. 77 static const SpeculatedType SpecNonIntAsDouble = 1ull << 29; // It's definitely not an Int52 but it's a real number and it's a double. 76 78 static const SpeculatedType SpecDoubleReal = SpecNonIntAsDouble | SpecAnyIntAsDouble; // It's definitely a non-NaN double. 77 static const SpeculatedType SpecDoublePureNaN = 1ull << 28; // It's definitely a NaN that is sae to tag (i.e. pure).78 static const SpeculatedType SpecDoubleImpureNaN = 1ull << 29; // It's definitely a NaN that is unsafe to tag (i.e. impure).79 static const SpeculatedType SpecDoublePureNaN = 1ull << 30; // It's definitely a NaN that is sae to tag (i.e. pure). 80 static const SpeculatedType SpecDoubleImpureNaN = 1ull << 31; // It's definitely a NaN that is unsafe to tag (i.e. impure). 79 81 static const SpeculatedType SpecDoubleNaN = SpecDoublePureNaN | SpecDoubleImpureNaN; // It's definitely some kind of NaN. 80 82 static const SpeculatedType SpecBytecodeDouble = SpecDoubleReal | SpecDoublePureNaN; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN. … … 84 86 static const SpeculatedType SpecBytecodeNumber = SpecInt32Only | SpecBytecodeDouble; // It's either an Int32 or a Double, and the Double cannot be an impure NaN. 85 87 static const SpeculatedType SpecFullNumber = SpecAnyInt | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN. 86 static const SpeculatedType SpecBoolean = 1ull << 3 0; // It's definitely a Boolean.87 static const SpeculatedType SpecOther = 1ull << 3 1; // It's definitely either Null or Undefined.88 static const SpeculatedType SpecBoolean = 1ull << 32; // It's definitely a Boolean. 89 static const SpeculatedType SpecOther = 1ull << 33; // It's definitely either Null or Undefined. 88 90 static const SpeculatedType SpecMisc = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined. 89 91 static const SpeculatedType SpecHeapTop = SpecCell | SpecBytecodeNumber | SpecMisc; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. 90 92 static const SpeculatedType SpecPrimitive = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc; // It's any non-Object JSValue. 91 static const SpeculatedType SpecEmpty = 1ull << 3 2; // It's definitely an empty value marker.93 static const SpeculatedType SpecEmpty = 1ull << 34; // It's definitely an empty value marker. 92 94 static const SpeculatedType SpecBytecodeTop = SpecHeapTop | SpecEmpty; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. Corresponds to what could be found in a bytecode local. 93 95 static const SpeculatedType SpecFullTop = SpecBytecodeTop | SpecFullNumber; // It can be anything that bytecode could see plus exotic encodings of numbers. … … 169 171 { 170 172 return value == SpecFunction; 173 } 174 175 inline bool isProxyObjectSpeculation(SpeculatedType value) 176 { 177 return value == SpecProxyObject; 178 } 179 180 inline bool isDerivedArraySpeculation(SpeculatedType value) 181 { 182 return value == SpecDerivedArray; 171 183 } 172 184 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r204994 r206065 632 632 633 633 RegisterID* emitIsJSArray(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_is_jsarray, dst, src); } 634 RegisterID* emitIsProxyObject(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_is_proxy_object, dst, src); } 634 635 RegisterID* emitIsObject(RegisterID* dst, RegisterID* src); 635 636 RegisterID* emitIsUndefined(RegisterID* dst, RegisterID* src); 636 637 RegisterID* emitIsEmpty(RegisterID* dst, RegisterID* src); 638 RegisterID* emitIsDerivedArray(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_is_derived_array, dst, src); } 637 639 void emitRequireObjectCoercible(RegisterID* value, const String& error); 638 640 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r205944 r206065 947 947 } 948 948 949 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_is Object(BytecodeGenerator& generator,RegisterID* dst)949 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isProxyObject(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst) 950 950 { 951 951 ArgumentListNode* node = m_args->m_listNode; … … 953 953 ASSERT(!node->m_next); 954 954 955 return generator.moveToDestinationIfNeeded(dst, generator.emitIsProxyObject(generator.tempDestination(dst), src.get())); 956 } 957 958 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isObject(BytecodeGenerator& generator, RegisterID* dst) 959 { 960 ArgumentListNode* node = m_args->m_listNode; 961 RefPtr<RegisterID> src = generator.emitNode(node); 962 ASSERT(!node->m_next); 963 955 964 return generator.moveToDestinationIfNeeded(dst, generator.emitIsObject(generator.tempDestination(dst), src.get())); 965 } 966 967 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isDerivedArray(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst) 968 { 969 ArgumentListNode* node = m_args->m_listNode; 970 RefPtr<RegisterID> src = generator.emitNode(node); 971 ASSERT(!node->m_next); 972 973 return generator.moveToDestinationIfNeeded(dst, generator.emitIsDerivedArray(generator.tempDestination(dst), src.get())); 956 974 } 957 975 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r205974 r206065 1011 1011 1012 1012 case IsEmpty: 1013 case IsJSArray:1014 1013 case IsUndefined: 1015 1014 case IsBoolean: … … 1019 1018 case IsObjectOrNull: 1020 1019 case IsFunction: 1021 case Is RegExpObject:1020 case IsCellWithType: 1022 1021 case IsTypedArrayView: { 1023 1022 AbstractValue child = forNode(node->child1()); … … 1025 1024 bool constantWasSet = true; 1026 1025 switch (node->op()) { 1027 case Is JSArray:1028 setConstant(node, jsBoolean(child.value().is Object() && child.value().getObject()->type() == ArrayType));1026 case IsCellWithType: 1027 setConstant(node, jsBoolean(child.value().isCell() && child.value().asCell()->type() == node->queriedType())); 1029 1028 break; 1030 1029 case IsUndefined: … … 1076 1075 setConstant(node, jsBoolean(false)); 1077 1076 break; 1078 case IsRegExpObject:1079 setConstant(node, jsBoolean(child.value().isObject() && child.value().getObject()->type() == RegExpObjectType));1080 break;1081 1077 case IsEmpty: 1082 1078 setConstant(node, jsBoolean(child.value().isEmpty())); … … 1099 1095 bool constantWasSet = false; 1100 1096 switch (node->op()) { 1101 case IsJSArray:1102 // We don't have a SpeculatedType for Proxies yet so we can't do better at proving false.1103 if (!(child.m_type & ~SpecArray)) {1104 setConstant(node, jsBoolean(true));1105 constantWasSet = true;1106 break;1107 }1108 1109 if (!(child.m_type & SpecObject)) {1110 setConstant(node, jsBoolean(false));1111 constantWasSet = true;1112 break;1113 }1114 1115 break;1116 1097 case IsEmpty: { 1117 1098 if (child.m_type && !(child.m_type & SpecEmpty)) { … … 1242 1223 break; 1243 1224 1244 case IsRegExpObject: 1245 // We don't have a SpeculatedType for Proxies yet so we can't do better at proving false. 1246 if (!(child.m_type & ~SpecRegExpObject)) { 1225 case IsCellWithType: 1226 if (!(child.m_type & ~node->speculatedTypeForQuery())) { 1247 1227 setConstant(node, jsBoolean(true)); 1248 1228 constantWasSet = true; 1249 1229 break; 1250 1230 } 1251 if (!(child.m_type & SpecObject)) {1231 if (!(child.m_type & node->speculatedTypeForQuery())) { 1252 1232 setConstant(node, jsBoolean(false)); 1253 1233 constantWasSet = true; -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r205974 r206065 2367 2367 2368 2368 insertChecks(); 2369 Node* isRegExpObject = addToGraph(Is RegExpObject, OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset)));2369 Node* isRegExpObject = addToGraph(IsCellWithType, OpInfo(RegExpObjectType), OpInfo(SpecRegExpObject), get(virtualRegisterForArgument(1, registerOffset))); 2370 2370 set(VirtualRegister(resultOperand), isRegExpObject); 2371 2371 return true; … … 3979 3979 case op_is_jsarray: { 3980 3980 Node* value = get(VirtualRegister(currentInstruction[2].u.operand)); 3981 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(Is JSArray, value));3981 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsCellWithType, OpInfo(ArrayType), OpInfo(SpecArray), value)); 3982 3982 NEXT_OPCODE(op_is_jsarray); 3983 } 3984 3985 case op_is_proxy_object: { 3986 Node* value = get(VirtualRegister(currentInstruction[2].u.operand)); 3987 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsCellWithType, OpInfo(ProxyObjectType), OpInfo(SpecProxyObject), value)); 3988 NEXT_OPCODE(op_is_proxy_object); 3983 3989 } 3984 3990 … … 3999 4005 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsFunction, value)); 4000 4006 NEXT_OPCODE(op_is_function); 4007 } 4008 4009 case op_is_derived_array: { 4010 Node* value = get(VirtualRegister(currentInstruction[2].u.operand)); 4011 set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsCellWithType, OpInfo(DerivedArrayType), OpInfo(SpecDerivedArray), value)); 4012 NEXT_OPCODE(op_is_derived_array); 4001 4013 } 4002 4014 -
trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
r204958 r206065 143 143 case op_is_string: 144 144 case op_is_jsarray: 145 case op_is_proxy_object: 145 146 case op_is_object: 146 147 case op_is_object_or_null: 147 148 case op_is_function: 149 case op_is_derived_array: 148 150 case op_not: 149 151 case op_less: -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r205974 r206065 159 159 case CompareStrictEq: 160 160 case CompareEqPtr: 161 case IsJSArray:162 161 case IsEmpty: 163 162 case IsUndefined: … … 166 165 case IsString: 167 166 case IsObject: 168 case IsRegExpObject:169 167 case IsTypedArrayView: 170 168 case LogicalNot: … … 214 212 write(Heap); 215 213 } 214 return; 215 216 case IsCellWithType: 217 def(PureValue(node, node->queriedType())); 216 218 return; 217 219 -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r205828 r206065 158 158 case InstanceOf: 159 159 case InstanceOfCustom: 160 case IsJSArray:161 160 case IsEmpty: 162 161 case IsUndefined: … … 167 166 case IsObjectOrNull: 168 167 case IsFunction: 169 case Is RegExpObject:168 case IsCellWithType: 170 169 case IsTypedArrayView: 171 170 case TypeOf: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r206047 r206065 1418 1418 break; 1419 1419 1420 case IsJSArray: 1421 if (node->child1()->shouldSpeculateArray()) { 1422 m_insertionSet.insertNode( 1423 m_indexInBlock, SpecNone, Check, node->origin, 1424 Edge(node->child1().node(), ArrayUse)); 1425 m_graph.convertToConstant(node, jsBoolean(true)); 1426 observeUseKindOnNode<ArrayUse>(node); 1427 } 1428 break; 1420 case IsCellWithType: { 1421 fixupIsCellWithType(node); 1422 break; 1423 } 1429 1424 1430 1425 case GetEnumerableLength: { … … 1640 1635 case IsObjectOrNull: 1641 1636 case IsFunction: 1642 case IsRegExpObject:1643 1637 case CreateDirectArguments: 1644 1638 case CreateClonedArguments: … … 1768 1762 ASSERT(!node->child3()); 1769 1763 node->convertToIdentity(); 1764 } 1765 } 1766 1767 void fixupIsCellWithType(Node* node) 1768 { 1769 switch (node->speculatedTypeForQuery()) { 1770 case SpecProxyObject: 1771 if (node->child1()->shouldSpeculateProxyObject()) { 1772 m_insertionSet.insertNode( 1773 m_indexInBlock, SpecNone, Check, node->origin, 1774 Edge(node->child1().node(), ProxyObjectUse)); 1775 m_graph.convertToConstant(node, jsBoolean(true)); 1776 observeUseKindOnNode<ProxyObjectUse>(node); 1777 return; 1778 } 1779 break; 1780 1781 case SpecRegExpObject: 1782 if (node->child1()->shouldSpeculateRegExpObject()) { 1783 m_insertionSet.insertNode( 1784 m_indexInBlock, SpecNone, Check, node->origin, 1785 Edge(node->child1().node(), RegExpObjectUse)); 1786 m_graph.convertToConstant(node, jsBoolean(true)); 1787 observeUseKindOnNode<RegExpObjectUse>(node); 1788 return; 1789 } 1790 break; 1791 1792 case SpecArray: 1793 if (node->child1()->shouldSpeculateArray()) { 1794 m_insertionSet.insertNode( 1795 m_indexInBlock, SpecNone, Check, node->origin, 1796 Edge(node->child1().node(), ArrayUse)); 1797 m_graph.convertToConstant(node, jsBoolean(true)); 1798 observeUseKindOnNode<ArrayUse>(node); 1799 return; 1800 } 1801 break; 1802 1803 case SpecDerivedArray: 1804 if (node->child1()->shouldSpeculateDerivedArray()) { 1805 m_insertionSet.insertNode( 1806 m_indexInBlock, SpecNone, Check, node->origin, 1807 Edge(node->child1().node(), DerivedArrayUse)); 1808 m_graph.convertToConstant(node, jsBoolean(true)); 1809 observeUseKindOnNode<DerivedArrayUse>(node); 1810 return; 1811 } 1812 break; 1813 } 1814 1815 if (node->child1()->shouldSpeculateCell()) { 1816 fixEdge<CellUse>(node->child1()); 1817 return; 1818 } 1819 1820 if (node->child1()->shouldSpeculateNotCell()) { 1821 m_insertionSet.insertNode( 1822 m_indexInBlock, SpecNone, Check, node->origin, 1823 Edge(node->child1().node(), NotCellUse)); 1824 m_graph.convertToConstant(node, jsBoolean(false)); 1825 observeUseKindOnNode<NotCellUse>(node); 1826 return; 1770 1827 } 1771 1828 } -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r204393 r206065 268 268 } 269 269 } 270 if (node->hasSpeculatedTypeForQuery()) 271 out.print(comma, SpeculationDump(node->speculatedTypeForQuery())); 270 272 if (node->hasStorageAccessData()) { 271 273 StorageAccessData& storageAccessData = node->storageAccessData(); -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r205520 r206065 1160 1160 ASSERT(hasLoadVarargsData()); 1161 1161 return m_opInfo.as<LoadVarargsData*>(); 1162 } 1163 1164 bool hasQueriedType() 1165 { 1166 return op() == IsCellWithType; 1167 } 1168 1169 JSType queriedType() 1170 { 1171 static_assert(std::is_same<uint8_t, std::underlying_type<JSType>::type>::value, "Ensure that uint8_t is the underlying type for JSType."); 1172 return static_cast<JSType>(m_opInfo.as<uint32_t>()); 1173 } 1174 1175 bool hasSpeculatedTypeForQuery() 1176 { 1177 return op() == IsCellWithType; 1178 } 1179 1180 SpeculatedType speculatedTypeForQuery() 1181 { 1182 return m_opInfo2.as<SpeculatedType>(); 1162 1183 } 1163 1184 … … 2060 2081 return isArraySpeculation(prediction()); 2061 2082 } 2083 2084 bool shouldSpeculateProxyObject() 2085 { 2086 return isProxyObjectSpeculation(prediction()); 2087 } 2088 2089 bool shouldSpeculateDerivedArray() 2090 { 2091 return isDerivedArraySpeculation(prediction()); 2092 } 2062 2093 2063 2094 bool shouldSpeculateDirectArguments() -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r205974 r206065 310 310 macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \ 311 311 \ 312 macro(Is JSArray, NodeResultBoolean) \312 macro(IsCellWithType, NodeResultBoolean) \ 313 313 macro(IsEmpty, NodeResultBoolean) \ 314 314 macro(IsUndefined, NodeResultBoolean) \ … … 319 319 macro(IsObjectOrNull, NodeResultBoolean) \ 320 320 macro(IsFunction, NodeResultBoolean) \ 321 macro(IsRegExpObject, NodeResultBoolean) \322 321 macro(IsTypedArrayView, NodeResultBoolean) \ 323 322 macro(TypeOf, NodeResultJS) \ -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r205974 r206065 794 794 case InstanceOf: 795 795 case InstanceOfCustom: 796 case IsJSArray:797 796 case IsEmpty: 798 797 case IsUndefined: … … 803 802 case IsObjectOrNull: 804 803 case IsFunction: 805 case Is RegExpObject:804 case IsCellWithType: 806 805 case IsTypedArrayView: { 807 806 setPrediction(SpecBoolean); -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r206047 r206065 60 60 case FinalObjectUse: 61 61 case RegExpObjectUse: 62 case ProxyObjectUse: 63 case DerivedArrayUse: 62 64 case MapObjectUse: 63 65 case SetObjectUse: … … 262 264 case InstanceOf: 263 265 case InstanceOfCustom: 264 case IsJSArray:265 266 case IsEmpty: 266 267 case IsUndefined: … … 271 272 case IsObjectOrNull: 272 273 case IsFunction: 273 case Is RegExpObject:274 case IsCellWithType: 274 275 case IsTypedArrayView: 275 276 case TypeOf: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r206047 r206065 3604 3604 } 3605 3605 3606 void SpeculativeJIT::compileIsJSArray(Node* node) 3607 { 3608 JSValueOperand value(this, node->child1()); 3609 GPRFlushedCallResult result(this); 3610 3611 JSValueRegs valueRegs = value.jsValueRegs(); 3612 GPRReg resultGPR = result.gpr(); 3613 3614 JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(valueRegs); 3615 3616 m_jit.compare8(JITCompiler::Equal, 3617 JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoTypeOffset()), 3618 TrustedImm32(ArrayType), 3619 resultGPR); 3620 blessBoolean(resultGPR); 3621 JITCompiler::Jump done = m_jit.jump(); 3622 3623 isNotCell.link(&m_jit); 3624 moveFalseTo(resultGPR); 3625 3626 done.link(&m_jit); 3627 blessedBooleanResult(resultGPR, node); 3628 } 3629 3630 void SpeculativeJIT::compileIsRegExpObject(Node* node) 3631 { 3632 JSValueOperand value(this, node->child1()); 3633 GPRFlushedCallResult result(this); 3634 3635 JSValueRegs valueRegs = value.jsValueRegs(); 3636 GPRReg resultGPR = result.gpr(); 3637 3638 JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(valueRegs); 3639 3640 m_jit.compare8(JITCompiler::Equal, 3641 JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoTypeOffset()), 3642 TrustedImm32(RegExpObjectType), 3643 resultGPR); 3644 blessBoolean(resultGPR); 3645 JITCompiler::Jump done = m_jit.jump(); 3646 3647 isNotCell.link(&m_jit); 3648 moveFalseTo(resultGPR); 3649 3650 done.link(&m_jit); 3651 blessedBooleanResult(resultGPR, node); 3606 void SpeculativeJIT::compileIsCellWithType(Node* node) 3607 { 3608 switch (node->child1().useKind()) { 3609 case UntypedUse: { 3610 JSValueOperand value(this, node->child1()); 3611 #if USE(JSVALUE64) 3612 GPRTemporary result(this, Reuse, value); 3613 #else 3614 GPRTemporary result(this, Reuse, value, PayloadWord); 3615 #endif 3616 3617 JSValueRegs valueRegs = value.jsValueRegs(); 3618 GPRReg resultGPR = result.gpr(); 3619 3620 JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(valueRegs); 3621 3622 m_jit.compare8(JITCompiler::Equal, 3623 JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoTypeOffset()), 3624 TrustedImm32(node->queriedType()), 3625 resultGPR); 3626 blessBoolean(resultGPR); 3627 JITCompiler::Jump done = m_jit.jump(); 3628 3629 isNotCell.link(&m_jit); 3630 moveFalseTo(resultGPR); 3631 3632 done.link(&m_jit); 3633 blessedBooleanResult(resultGPR, node); 3634 return; 3635 } 3636 3637 case CellUse: { 3638 SpeculateCellOperand cell(this, node->child1()); 3639 GPRTemporary result(this, Reuse, cell); 3640 3641 GPRReg cellGPR = cell.gpr(); 3642 GPRReg resultGPR = result.gpr(); 3643 3644 m_jit.compare8(JITCompiler::Equal, 3645 JITCompiler::Address(cellGPR, JSCell::typeInfoTypeOffset()), 3646 TrustedImm32(node->queriedType()), 3647 resultGPR); 3648 blessBoolean(resultGPR); 3649 blessedBooleanResult(resultGPR, node); 3650 return; 3651 } 3652 3653 default: 3654 RELEASE_ASSERT_NOT_REACHED(); 3655 break; 3656 } 3652 3657 } 3653 3658 … … 7409 7414 } 7410 7415 7416 void SpeculativeJIT::speculateProxyObject(Edge edge, GPRReg cell) 7417 { 7418 speculateCellType(edge, cell, SpecProxyObject, ProxyObjectType); 7419 } 7420 7421 void SpeculativeJIT::speculateProxyObject(Edge edge) 7422 { 7423 if (!needsTypeCheck(edge, SpecProxyObject)) 7424 return; 7425 7426 SpeculateCellOperand operand(this, edge); 7427 speculateProxyObject(edge, operand.gpr()); 7428 } 7429 7430 void SpeculativeJIT::speculateDerivedArray(Edge edge, GPRReg cell) 7431 { 7432 speculateCellType(edge, cell, SpecDerivedArray, DerivedArrayType); 7433 } 7434 7435 void SpeculativeJIT::speculateDerivedArray(Edge edge) 7436 { 7437 if (!needsTypeCheck(edge, SpecDerivedArray)) 7438 return; 7439 7440 SpeculateCellOperand operand(this, edge); 7441 speculateDerivedArray(edge, operand.gpr()); 7442 } 7443 7411 7444 void SpeculativeJIT::speculateMapObject(Edge edge, GPRReg cell) 7412 7445 { … … 7726 7759 case RegExpObjectUse: 7727 7760 speculateRegExpObject(edge); 7761 break; 7762 case ProxyObjectUse: 7763 speculateProxyObject(edge); 7764 break; 7765 case DerivedArrayUse: 7766 speculateDerivedArray(edge); 7728 7767 break; 7729 7768 case MapObjectUse: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r206047 r206065 756 756 void compileInstanceOfCustom(Node*); 757 757 758 void compileIsJSArray(Node*); 759 void compileIsRegExpObject(Node*); 758 void compileIsCellWithType(Node*); 760 759 void compileIsTypedArrayView(Node*); 761 760 … … 2681 2680 void speculateRegExpObject(Edge, GPRReg cell); 2682 2681 void speculateRegExpObject(Edge); 2682 void speculateProxyObject(Edge, GPRReg cell); 2683 void speculateProxyObject(Edge); 2684 void speculateDerivedArray(Edge, GPRReg cell); 2685 void speculateDerivedArray(Edge); 2683 2686 void speculateMapObject(Edge); 2684 2687 void speculateMapObject(Edge, GPRReg cell); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r205828 r206065 4661 4661 } 4662 4662 4663 case IsJSArray: {4664 compileIsJSArray(node);4665 break;4666 }4667 4668 4663 case IsObject: { 4669 4664 JSValueOperand value(this, node->child1()); … … 4696 4691 } 4697 4692 4698 case Is RegExpObject: {4699 compileIs RegExpObject(node);4693 case IsCellWithType: { 4694 compileIsCellWithType(node); 4700 4695 break; 4701 4696 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r205828 r206065 4633 4633 } 4634 4634 4635 case IsJSArray: {4636 compileIsJSArray(node);4637 break;4638 }4639 4640 4635 case MapHash: { 4641 4636 JSValueOperand input(this, node->child1()); … … 4831 4826 } 4832 4827 4833 case Is RegExpObject: {4834 compileIs RegExpObject(node);4828 case IsCellWithType: { 4829 compileIsCellWithType(node); 4835 4830 break; 4836 4831 } -
trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp
r206047 r206065 98 98 out.print("RegExpObject"); 99 99 return; 100 case ProxyObjectUse: 101 out.print("ProxyObject"); 102 return; 103 case DerivedArrayUse: 104 out.print("DerivedArray"); 105 return; 100 106 case MapObjectUse: 101 107 out.print("MapObjectUse"); -
trunk/Source/JavaScriptCore/dfg/DFGUseKind.h
r206047 r206065 58 58 FinalObjectUse, 59 59 RegExpObjectUse, 60 ProxyObjectUse, 61 DerivedArrayUse, 60 62 ObjectOrOtherUse, 61 63 StringIdentUse, … … 127 129 case RegExpObjectUse: 128 130 return SpecRegExpObject; 131 case ProxyObjectUse: 132 return SpecProxyObject; 133 case DerivedArrayUse: 134 return SpecDerivedArray; 129 135 case ObjectOrOtherUse: 130 136 return SpecObject | SpecOther; … … 226 232 case FinalObjectUse: 227 233 case RegExpObjectUse: 234 case ProxyObjectUse: 235 case DerivedArrayUse: 228 236 case StringIdentUse: 229 237 case StringUse: -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r206047 r206065 182 182 case Unreachable: 183 183 case In: 184 case Is JSArray:184 case IsCellWithType: 185 185 case MapHash: 186 186 case GetMapBucket: … … 195 195 case IsObjectOrNull: 196 196 case IsFunction: 197 case IsRegExpObject:198 197 case IsTypedArrayView: 199 198 case CheckTypeInfoFlags: … … 437 436 case FinalObjectUse: 438 437 case RegExpObjectUse: 438 case ProxyObjectUse: 439 case DerivedArrayUse: 439 440 case NotCellUse: 440 441 case OtherUse: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r206047 r206065 900 900 compileIsString(); 901 901 break; 902 case Is JSArray:903 compileIs JSArray();902 case IsCellWithType: 903 compileIsCellWithType(); 904 904 break; 905 905 case MapHash: … … 923 923 case IsFunction: 924 924 compileIsFunction(); 925 break;926 case IsRegExpObject:927 compileIsRegExpObject();928 925 break; 929 926 case IsTypedArrayView: … … 6287 6284 } 6288 6285 6289 void compileIsJSArray() 6290 { 6291 LValue value = lowJSValue(m_node->child1()); 6292 6293 LBasicBlock isCellCase = m_out.newBlock(); 6294 LBasicBlock continuation = m_out.newBlock(); 6295 6296 ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse); 6297 m_out.branch( 6298 isCell(value, provenType(m_node->child1())), unsure(isCellCase), unsure(continuation)); 6299 6300 LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation); 6301 ValueFromBlock cellResult = m_out.anchor(isArray(value, provenType(m_node->child1()))); 6302 m_out.jump(continuation); 6303 6304 m_out.appendTo(continuation, lastNext); 6305 setBoolean(m_out.phi(Int32, notCellResult, cellResult)); 6286 void compileIsCellWithType() 6287 { 6288 if (m_node->child1().useKind() == UntypedUse) { 6289 LValue value = lowJSValue(m_node->child1()); 6290 6291 LBasicBlock isCellCase = m_out.newBlock(); 6292 LBasicBlock continuation = m_out.newBlock(); 6293 6294 ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse); 6295 m_out.branch( 6296 isCell(value, provenType(m_node->child1())), unsure(isCellCase), unsure(continuation)); 6297 6298 LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation); 6299 ValueFromBlock cellResult = m_out.anchor(isCellWithType(value, m_node->queriedType(), m_node->speculatedTypeForQuery(), provenType(m_node->child1()))); 6300 m_out.jump(continuation); 6301 6302 m_out.appendTo(continuation, lastNext); 6303 setBoolean(m_out.phi(Int32, notCellResult, cellResult)); 6304 } else { 6305 ASSERT(m_node->child1().useKind() == CellUse); 6306 setBoolean(isCellWithType(lowCell(m_node->child1()), m_node->queriedType(), m_node->speculatedTypeForQuery(), provenType(m_node->child1()))); 6307 } 6306 6308 } 6307 6309 … … 6646 6648 Int32, notCellResult, functionResult, objectResult, slowResult); 6647 6649 setBoolean(result); 6648 }6649 6650 void compileIsRegExpObject()6651 {6652 LValue value = lowJSValue(m_node->child1());6653 6654 LBasicBlock isCellCase = m_out.newBlock();6655 LBasicBlock continuation = m_out.newBlock();6656 6657 ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);6658 m_out.branch(6659 isCell(value, provenType(m_node->child1())), unsure(isCellCase), unsure(continuation));6660 6661 LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation);6662 ValueFromBlock cellResult = m_out.anchor(isRegExpObject(value, provenType(m_node->child1())));6663 m_out.jump(continuation);6664 6665 m_out.appendTo(continuation, lastNext);6666 setBoolean(m_out.phi(Int32, notCellResult, cellResult));6667 6650 } 6668 6651 … … 10692 10675 speculateRegExpObject(edge); 10693 10676 break; 10677 case ProxyObjectUse: 10678 speculateProxyObject(edge); 10679 break; 10680 case DerivedArrayUse: 10681 speculateDerivedArray(edge); 10682 break; 10694 10683 case MapObjectUse: 10695 10684 speculateMapObject(edge); … … 10787 10776 } 10788 10777 10789 LValue is Array(LValue cell, SpeculatedType type = SpecFullTop)10790 { 10791 if (LValue proven = isProvenValue(type & SpecCell, SpecArray))10778 LValue isCellWithType(LValue cell, JSType queriedType, SpeculatedType speculatedTypeForQuery, SpeculatedType type = SpecFullTop) 10779 { 10780 if (LValue proven = isProvenValue(type & SpecCell, speculatedTypeForQuery)) 10792 10781 return proven; 10793 10782 return m_out.equal( 10794 10783 m_out.load8ZeroExt32(cell, m_heaps.JSCell_typeInfoType), 10795 m_out.constInt32( ArrayType));10784 m_out.constInt32(queriedType)); 10796 10785 } 10797 10786 … … 10934 10923 } 10935 10924 10936 LValue isRegExpObject(LValue cell, SpeculatedType type = SpecFullTop)10937 {10938 if (LValue proven = isProvenValue(type & SpecCell, SpecRegExpObject))10939 return proven;10940 return m_out.equal(10941 m_out.load8ZeroExt32(cell, m_heaps.JSCell_typeInfoType),10942 m_out.constInt32(RegExpObjectType));10943 }10944 10945 10925 LValue isType(LValue cell, JSType type) 10946 10926 { … … 11036 11016 { 11037 11017 speculateRegExpObject(edge, lowCell(edge)); 11018 } 11019 11020 void speculateProxyObject(Edge edge, LValue cell) 11021 { 11022 FTL_TYPE_CHECK( 11023 jsValueValue(cell), edge, SpecProxyObject, isNotType(cell, ProxyObjectType)); 11024 } 11025 11026 void speculateProxyObject(Edge edge) 11027 { 11028 speculateProxyObject(edge, lowCell(edge)); 11029 } 11030 11031 void speculateDerivedArray(Edge edge, LValue cell) 11032 { 11033 FTL_TYPE_CHECK( 11034 jsValueValue(cell), edge, SpecDerivedArray, isNotType(cell, DerivedArrayType)); 11035 } 11036 11037 void speculateDerivedArray(Edge edge) 11038 { 11039 speculateDerivedArray(edge, lowCell(edge)); 11038 11040 } 11039 11041 -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r205675 r206065 271 271 DEFINE_OP(op_is_string) 272 272 DEFINE_OP(op_is_jsarray) 273 DEFINE_OP(op_is_proxy_object) 273 274 DEFINE_OP(op_is_object) 275 DEFINE_OP(op_is_derived_array) 274 276 DEFINE_OP(op_jeq_null) 275 277 DEFINE_OP(op_jfalse) -
trunk/Source/JavaScriptCore/jit/JIT.h
r205675 r206065 401 401 int32_t getOperandConstantInt(int src); 402 402 double getOperandConstantDouble(int src); 403 404 void emitIsCellWithType(Instruction*, JSType); 403 405 404 406 #if USE(JSVALUE32_64) … … 517 519 void emit_op_is_string(Instruction*); 518 520 void emit_op_is_jsarray(Instruction*); 521 void emit_op_is_proxy_object(Instruction*); 519 522 void emit_op_is_object(Instruction*); 523 void emit_op_is_derived_array(Instruction*); 520 524 void emit_op_jeq_null(Instruction*); 521 525 void emit_op_jfalse(Instruction*); -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r205675 r206065 244 244 } 245 245 246 void JIT::emit _op_is_string(Instruction* currentInstruction)246 void JIT::emitIsCellWithType(Instruction* currentInstruction, JSType type) 247 247 { 248 248 int dst = currentInstruction[1].u.operand; 249 249 int value = currentInstruction[2].u.operand; 250 250 251 251 emitGetVirtualRegister(value, regT0); 252 252 Jump isNotCell = emitJumpIfNotJSCell(regT0); 253 254 compare8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32( StringType), regT0);253 254 compare8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(type), regT0); 255 255 emitTagBool(regT0); 256 256 Jump done = jump(); 257 257 258 258 isNotCell.link(this); 259 259 move(TrustedImm32(ValueFalse), regT0); 260 260 261 261 done.link(this); 262 262 emitPutVirtualRegister(dst); 263 263 } 264 264 265 void JIT::emit_op_is_string(Instruction* currentInstruction) 266 { 267 emitIsCellWithType(currentInstruction, StringType); 268 } 269 265 270 void JIT::emit_op_is_jsarray(Instruction* currentInstruction) 266 271 { 267 int dst = currentInstruction[1].u.operand; 268 int value = currentInstruction[2].u.operand; 269 270 emitGetVirtualRegister(value, regT0); 271 Jump isNotCell = emitJumpIfNotJSCell(regT0); 272 273 compare8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ArrayType), regT0); 274 emitTagBool(regT0); 275 Jump done = jump(); 276 277 isNotCell.link(this); 278 move(TrustedImm32(ValueFalse), regT0); 279 280 done.link(this); 281 emitPutVirtualRegister(dst); 272 emitIsCellWithType(currentInstruction, ArrayType); 273 } 274 275 void JIT::emit_op_is_proxy_object(Instruction* currentInstruction) 276 { 277 emitIsCellWithType(currentInstruction, ProxyObjectType); 278 } 279 280 void JIT::emit_op_is_derived_array(Instruction* currentInstruction) 281 { 282 emitIsCellWithType(currentInstruction, DerivedArrayType); 282 283 } 283 284 -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r205675 r206065 355 355 } 356 356 357 void JIT::emit _op_is_string(Instruction* currentInstruction)357 void JIT::emitIsCellWithType(Instruction* currentInstruction, JSType type) 358 358 { 359 359 int dst = currentInstruction[1].u.operand; 360 360 int value = currentInstruction[2].u.operand; 361 361 362 362 emitLoad(value, regT1, regT0); 363 363 Jump isNotCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)); 364 365 compare8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32( StringType), regT0);364 365 compare8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(type), regT0); 366 366 Jump done = jump(); 367 367 368 368 isNotCell.link(this); 369 369 move(TrustedImm32(0), regT0); 370 370 371 371 done.link(this); 372 372 emitStoreBool(dst, regT0); 373 373 } 374 374 375 void JIT::emit_op_is_string(Instruction* currentInstruction) 376 { 377 emitIsCellWithType(currentInstruction, StringType); 378 } 379 375 380 void JIT::emit_op_is_jsarray(Instruction* currentInstruction) 376 381 { 377 int dst = currentInstruction[1].u.operand; 378 int value = currentInstruction[2].u.operand; 379 380 emitLoad(value, regT1, regT0); 381 Jump isNotCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)); 382 383 compare8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ArrayType), regT0); 384 Jump done = jump(); 385 386 isNotCell.link(this); 387 move(TrustedImm32(0), regT0); 388 389 done.link(this); 390 emitStoreBool(dst, regT0); 382 emitIsCellWithType(currentInstruction, ArrayType); 383 } 384 385 void JIT::emit_op_is_proxy_object(Instruction* currentInstruction) 386 { 387 emitIsCellWithType(currentInstruction, ProxyObjectType); 388 } 389 390 void JIT::emit_op_is_derived_array(Instruction* currentInstruction) 391 { 392 emitIsCellWithType(currentInstruction, DerivedArrayType); 391 393 } 392 394 -
trunk/Source/JavaScriptCore/jsc.cpp
r205880 r206065 456 456 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 457 457 { 458 return Structure::create(vm, globalObject, prototype, TypeInfo( ObjectType, StructureFlags), info(), ArrayClass);458 return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass); 459 459 } 460 460 -
trunk/Source/JavaScriptCore/llint/LLIntData.cpp
r205462 r206065 160 160 STATIC_ASSERT(FinalObjectType == 21); 161 161 STATIC_ASSERT(JSFunctionType == 23); 162 STATIC_ASSERT(ArrayType == 29); 162 STATIC_ASSERT(ArrayType == 31); 163 STATIC_ASSERT(DerivedArrayType == 32); 164 STATIC_ASSERT(ProxyObjectType == 116); 163 165 STATIC_ASSERT(Int8ArrayType == 100); 164 166 STATIC_ASSERT(Int16ArrayType == 101); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r205462 r206065 347 347 const FinalObjectType = 21 348 348 const JSFunctionType = 23 349 const ArrayType = 29 349 const ArrayType = 31 350 const DerivedArrayType = 32 351 const ProxyObjectType = 116 350 352 351 353 # The typed array types need to be numbered in a particular order because of the manually written -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r205462 r206065 1258 1258 1259 1259 1260 _llint_op_is_string: 1261 traceExecution() 1260 macro isCellWithType(type) 1262 1261 loadi 8[PC], t1 1263 1262 loadi 4[PC], t2 1264 1263 loadConstantOrVariable(t1, t0, t3) 1265 1264 storei BooleanTag, TagOffset[cfr, t2, 8] 1266 bineq t0, CellTag, . opIsStringNotCell1267 cbeq JSCell::m_type[t3], StringType, t11265 bineq t0, CellTag, .notCellCase 1266 cbeq JSCell::m_type[t3], type, t1 1268 1267 storei t1, PayloadOffset[cfr, t2, 8] 1269 1268 dispatch(3) 1270 . opIsStringNotCell:1269 .notCellCase: 1271 1270 storep 0, PayloadOffset[cfr, t2, 8] 1272 1271 dispatch(3) 1272 end 1273 1274 1275 _llint_op_is_string: 1276 traceExecution() 1277 isCellWithType(StringType) 1273 1278 1274 1279 1275 1280 _llint_op_is_jsarray: 1276 1281 traceExecution() 1277 loadi 8[PC], t11278 loadi 4[PC], t2 1279 loadConstantOrVariable(t1, t0, t3) 1280 storei BooleanTag, TagOffset[cfr, t2, 8] 1281 bineq t0, CellTag, .opIsJSArrayNotCell1282 cbeq JSCell::m_type[t3], ArrayType, t11283 storei t1, PayloadOffset[cfr, t2, 8] 1284 dispatch(3) 1285 .opIsJSArrayNotCell:1286 storep 0, PayloadOffset[cfr, t2, 8]1287 dispatch(3)1282 isCellWithType(ArrayType) 1283 1284 1285 _llint_op_is_proxy_object: 1286 traceExecution() 1287 isCellWithType(ProxyObjectType) 1288 1289 1290 _llint_op_is_derived_array: 1291 traceExecution() 1292 isCellWithType(DerivedArrayType) 1288 1293 1289 1294 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r205462 r206065 1147 1147 1148 1148 1149 _llint_op_is_string: 1150 traceExecution() 1149 macro isCellWithType(type) 1151 1150 loadisFromInstruction(2, t1) 1152 1151 loadisFromInstruction(1, t2) 1153 1152 loadConstantOrVariable(t1, t0) 1154 btqnz t0, tagMask, . opIsStringNotCell1155 cbeq JSCell::m_type[t0], StringType, t11153 btqnz t0, tagMask, .notCellCase 1154 cbeq JSCell::m_type[t0], type, t1 1156 1155 orq ValueFalse, t1 1157 1156 storeq t1, [cfr, t2, 8] 1158 1157 dispatch(3) 1159 . opIsStringNotCell:1158 .notCellCase: 1160 1159 storeq ValueFalse, [cfr, t2, 8] 1161 1160 dispatch(3) 1161 end 1162 1163 1164 _llint_op_is_string: 1165 traceExecution() 1166 isCellWithType(StringType) 1162 1167 1163 1168 1164 1169 _llint_op_is_jsarray: 1165 1170 traceExecution() 1166 loadisFromInstruction(2, t1)1167 loadisFromInstruction(1, t2) 1168 loadConstantOrVariable(t1, t0) 1169 btqnz t0, tagMask, .opIsJSArrayNotCell 1170 cbeq JSCell::m_type[t0], ArrayType, t11171 orq ValueFalse, t11172 storeq t1, [cfr, t2, 8] 1173 dispatch(3) 1174 .opIsJSArrayNotCell:1175 storeq ValueFalse, [cfr, t2, 8]1176 dispatch(3)1171 isCellWithType(ArrayType) 1172 1173 1174 _llint_op_is_proxy_object: 1175 traceExecution() 1176 isCellWithType(ProxyObjectType) 1177 1178 1179 _llint_op_is_derived_array: 1180 traceExecution() 1181 isCellWithType(DerivedArrayType) 1177 1182 1178 1183 -
trunk/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
r205666 r206065 36 36 #include "JSCInlines.h" 37 37 38 namespace JSC {39 40 static EncodedJSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*);41 42 }43 44 38 #include "ArrayConstructor.lut.h" 45 39 … … 68 62 putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete); 69 63 putDirectNonIndexAccessor(vm, vm.propertyNames->speciesSymbol, speciesSymbol, Accessor | ReadOnly | DontEnum); 70 JSC_ NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->isArray, arrayConstructorIsArray, DontEnum, 1);64 JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->isArray, arrayConstructorIsArrayCodeGenerator, DontEnum); 71 65 } 72 66 … … 123 117 } 124 118 119 static ALWAYS_INLINE bool isArraySlowInline(ExecState* exec, ProxyObject* proxy) 120 { 121 VM& vm = exec->vm(); 122 auto scope = DECLARE_THROW_SCOPE(vm); 123 124 while (true) { 125 if (proxy->isRevoked()) { 126 throwTypeError(exec, scope, ASCIILiteral("Array.isArray cannot be called on a Proxy that has been revoked")); 127 return false; 128 } 129 JSObject* argument = proxy->target(); 130 131 if (argument->type() == ArrayType || argument->type() == DerivedArrayType) 132 return true; 133 134 if (argument->type() != ProxyObjectType) 135 return false; 136 137 proxy = jsCast<ProxyObject*>(argument); 138 } 139 140 ASSERT_NOT_REACHED(); 141 } 142 143 bool isArraySlow(ExecState* exec, ProxyObject* argument) 144 { 145 return isArraySlowInline(exec, argument); 146 } 147 125 148 // ES6 7.2.2 126 149 // https://tc39.github.io/ecma262/#sec-isarray 127 EncodedJSValue JSC_HOST_CALL arrayConstructor IsArray(ExecState* exec)150 EncodedJSValue JSC_HOST_CALL arrayConstructorPrivateFuncIsArraySlow(ExecState* exec) 128 151 { 129 return JSValue::encode(jsBoolean(isArray(exec, exec->argument(0)))); 152 ASSERT(jsDynamicCast<ProxyObject*>(exec->argument(0))); 153 return JSValue::encode(jsBoolean(isArraySlowInline(exec, jsCast<ProxyObject*>(exec->uncheckedArgument(0))))); 130 154 } 131 155 -
trunk/Source/JavaScriptCore/runtime/ArrayConstructor.h
r205198 r206065 65 65 66 66 EncodedJSValue JSC_HOST_CALL arrayConstructorPrivateFuncIsArrayConstructor(ExecState*); 67 EncodedJSValue JSC_HOST_CALL arrayConstructorPrivateFuncIsArraySlow(ExecState*); 68 bool isArraySlow(ExecState*, ProxyObject* argument); 67 69 68 70 // ES6 7.2.2 … … 70 72 inline bool isArray(ExecState* exec, JSValue argumentValue) 71 73 { 72 VM& vm = exec->vm();73 auto scope = DECLARE_THROW_SCOPE(vm);74 75 74 if (!argumentValue.isObject()) 76 75 return false; 77 76 78 77 JSObject* argument = jsCast<JSObject*>(argumentValue); 79 while (true) { 80 if (argument->inherits(JSArray::info())) 81 return true; 78 if (argument->type() == ArrayType || argument->type() == DerivedArrayType) 79 return true; 82 80 83 if (argument->type() != ProxyObjectType) 84 return false; 85 86 ProxyObject* proxy = jsCast<ProxyObject*>(argument); 87 if (proxy->isRevoked()) { 88 throwTypeError(exec, scope, ASCIILiteral("Array.isArray cannot be called on a Proxy that has been revoked")); 89 return false; 90 } 91 argument = proxy->target(); 92 } 93 94 ASSERT_NOT_REACHED(); 81 if (argument->type() != ProxyObjectType) 82 return false; 83 return isArraySlow(exec, jsCast<ProxyObject*>(argument)); 95 84 } 96 85 -
trunk/Source/JavaScriptCore/runtime/ArrayPrototype.h
r202125 r206065 48 48 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 49 49 { 50 return Structure::create(vm, globalObject, prototype, TypeInfo( ObjectType, StructureFlags), info(), ArrayClass);50 return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass); 51 51 } 52 52 -
trunk/Source/JavaScriptCore/runtime/JSArray.h
r205462 r206065 149 149 150 150 protected: 151 void finishCreation(VM& vm) 152 { 153 Base::finishCreation(vm); 154 ASSERT_WITH_MESSAGE(type() == ArrayType || type() == DerivedArrayType, "Instance inheriting JSArray should have either ArrayType or DerivedArrayType"); 155 } 156 151 157 static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); 152 158 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r205856 r206065 687 687 JSFunction* privateFuncThisNumberValue = JSFunction::create(vm, this, 0, String(), numberProtoFuncValueOf); 688 688 JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor); 689 JSFunction* privateFuncIsArraySlow = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArraySlow); 689 690 JSFunction* privateFuncConcatMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncConcatMemcpy); 690 691 JSFunction* privateFuncAppendMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncAppendMemcpy); … … 751 752 GlobalPropertyInfo(vm.propertyNames->builtinNames().isMapPrivateName(), JSFunction::create(vm, this, 1, String(), privateFuncIsMap), DontEnum | DontDelete | ReadOnly), 752 753 GlobalPropertyInfo(vm.propertyNames->builtinNames().isArrayPrivateName(), arrayConstructor->getDirect(vm, vm.propertyNames->isArray), DontEnum | DontDelete | ReadOnly), 754 GlobalPropertyInfo(vm.propertyNames->builtinNames().isArraySlowPrivateName(), privateFuncIsArraySlow, DontEnum | DontDelete | ReadOnly), 753 755 GlobalPropertyInfo(vm.propertyNames->builtinNames().isArrayConstructorPrivateName(), privateFuncIsArrayConstructor, DontEnum | DontDelete | ReadOnly), 754 756 GlobalPropertyInfo(vm.propertyNames->builtinNames().concatMemcpyPrivateName(), privateFuncConcatMemcpy, DontEnum | DontDelete | ReadOnly), -
trunk/Source/JavaScriptCore/runtime/JSType.h
r205520 r206065 61 61 ImpureProxyType, 62 62 WithScopeType, 63 ArrayType,64 63 DirectArgumentsType, 65 64 ScopedArgumentsType, 65 66 ArrayType, 67 DerivedArrayType, 66 68 67 69 Int8ArrayType = 100, -
trunk/Source/WebCore/ChangeLog
r206062 r206065 1 2016-09-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [DFG] Introduce IsCellWithType node and unify IsJSArray, IsRegExpObject and newly added IsProxyObject 4 https://bugs.webkit.org/show_bug.cgi?id=162000 5 6 Reviewed by Filip Pizlo. 7 8 * bridge/runtime_array.h: 9 (JSC::RuntimeArray::createStructure): 10 1 11 2016-09-16 Chris Dumez <cdumez@apple.com> 2 12 -
trunk/Source/WebCore/bridge/runtime_array.h
r201703 r206065 76 76 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 77 77 { 78 return Structure::create(vm, globalObject, prototype, TypeInfo( ObjectType, StructureFlags), info(), ArrayClass);78 return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass); 79 79 } 80 80
Note: See TracChangeset
for help on using the changeset viewer.