Changeset 121280 in webkit for trunk/Source/JavaScriptCore
- Timestamp:
- Jun 26, 2012, 12:42:05 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r121243 r121280 1 2012-06-25 Filip Pizlo <[email protected]> 2 3 DFG::operationNewArray is unnecessarily slow, and may use the wrong array 4 prototype when inlined 5 https://bugs.webkit.org/show_bug.cgi?id=89821 6 7 Reviewed by Geoffrey Garen. 8 9 Fixes all array allocations to use the right structure, and hence the right prototype. Adds 10 inlining of new Array(...) with a non-zero number of arguments. Optimizes allocations of 11 empty arrays. 12 13 * dfg/DFGAbstractState.cpp: 14 (JSC::DFG::AbstractState::execute): 15 * dfg/DFGByteCodeParser.cpp: 16 (JSC::DFG::ByteCodeParser::handleConstantInternalFunction): 17 * dfg/DFGCCallHelpers.h: 18 (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): 19 (CCallHelpers): 20 * dfg/DFGNodeType.h: 21 (DFG): 22 * dfg/DFGOperations.cpp: 23 * dfg/DFGOperations.h: 24 * dfg/DFGPredictionPropagationPhase.cpp: 25 (JSC::DFG::PredictionPropagationPhase::propagate): 26 * dfg/DFGSpeculativeJIT.h: 27 (JSC::DFG::SpeculativeJIT::callOperation): 28 * dfg/DFGSpeculativeJIT32_64.cpp: 29 (JSC::DFG::SpeculativeJIT::compile): 30 * dfg/DFGSpeculativeJIT64.cpp: 31 (JSC::DFG::SpeculativeJIT::compile): 32 * runtime/JSArray.h: 33 (JSC): 34 (JSC::constructArray): 35 * runtime/JSGlobalObject.h: 36 (JSC): 37 (JSC::constructArray): 38 1 39 2012-06-26 Filip Pizlo <[email protected]> 2 40 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r121215 r121280 1142 1142 case NewArrayBuffer: 1143 1143 node.setCanExit(false); 1144 forNode(nodeIndex).set(m_ codeBlock->globalObject()->arrayStructure());1144 forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructure()); 1145 1145 m_haveStructures = true; 1146 1146 break; 1147 1148 case NewArrayWithSize: 1149 speculateInt32Unary(node); 1150 forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructure()); 1151 m_haveStructures = true; 1152 break; 1147 1153 1148 1154 case NewRegexp: 1149 1155 node.setCanExit(false); 1150 forNode(nodeIndex).set(m_ codeBlock->globalObject()->regExpStructure());1156 forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->regExpStructure()); 1151 1157 m_haveStructures = true; 1152 1158 break; -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r121073 r121280 1607 1607 // is good enough. 1608 1608 1609 UNUSED_PARAM(registerOffset); // Remove this once we do more things to the arguments.1610 1609 UNUSED_PARAM(prediction); // Remove this once we do more things. 1611 1610 UNUSED_PARAM(kind); // Remove this once we do more things. 1612 1611 1613 1612 if (function->classInfo() == &ArrayConstructor::s_info) { 1614 // We could handle this but don't for now. 1615 if (argumentCountIncludingThis != 1) 1616 return false; 1617 1613 if (argumentCountIncludingThis == 2) { 1614 setIntrinsicResult( 1615 usesResult, resultOperand, 1616 addToGraph(NewArrayWithSize, get(registerOffset + argumentToOperand(1)))); 1617 return true; 1618 } 1619 1620 for (int i = 1; i < argumentCountIncludingThis; ++i) 1621 addVarArgChild(get(registerOffset + argumentToOperand(i))); 1618 1622 setIntrinsicResult( 1619 1623 usesResult, resultOperand, -
trunk/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
r120244 r121280 161 161 } 162 162 163 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2) 164 { 165 resetCallArguments(); 166 addCallArgument(GPRInfo::callFrameRegister); 167 addCallArgument(arg1); 168 addCallArgument(arg2); 169 } 170 163 171 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2) 164 172 { … … 196 204 197 205 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3) 206 { 207 resetCallArguments(); 208 addCallArgument(GPRInfo::callFrameRegister); 209 addCallArgument(arg1); 210 addCallArgument(arg2); 211 addCallArgument(arg3); 212 } 213 214 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3) 198 215 { 199 216 resetCallArguments(); … … 598 615 } 599 616 617 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3) 618 { 619 move(arg1, GPRInfo::argumentGPR1); 620 move(arg2, GPRInfo::argumentGPR2); 621 move(arg3, GPRInfo::argumentGPR3); 622 move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 623 } 624 600 625 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3) 601 626 { -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r120499 r121280 185 185 macro(NewObject, NodeResultJS) \ 186 186 macro(NewArray, NodeResultJS | NodeHasVarArgs) \ 187 macro(NewArrayWithSize, NodeResultJS) \ 187 188 macro(NewArrayBuffer, NodeResultJS) \ 188 189 macro(NewRegexp, NodeResultJS) \ -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r121215 r121280 1006 1006 } 1007 1007 1008 EncodedJSValue DFG_OPERATION operationNewArray(ExecState* exec, void* buffer, size_t size) 1009 { 1010 JSGlobalData* globalData = &exec->globalData(); 1011 NativeCallFrameTracer tracer(globalData, exec); 1012 1013 return JSValue::encode(constructArray(exec, static_cast<JSValue*>(buffer), size)); 1008 EncodedJSValue DFG_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size) 1009 { 1010 JSGlobalData* globalData = &exec->globalData(); 1011 NativeCallFrameTracer tracer(globalData, exec); 1012 1013 return JSValue::encode(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size)); 1014 } 1015 1016 EncodedJSValue DFG_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure) 1017 { 1018 return JSValue::encode(JSArray::create(exec->globalData(), arrayStructure)); 1019 } 1020 1021 EncodedJSValue DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size) 1022 { 1023 return JSValue::encode(JSArray::create(exec->globalData(), arrayStructure, size)); 1014 1024 } 1015 1025 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r121073 r121280 77 77 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EPS)(ExecState*, void*, size_t); 78 78 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ESS)(ExecState*, size_t, size_t); 79 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ESt)(ExecState*, Structure*); 80 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EStI)(ExecState*, Structure*, int32_t); 81 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EStPS)(ExecState*, Structure*, void*, size_t); 79 82 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EZ)(ExecState*, int32_t); 80 83 typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EZIcfZ)(ExecState*, int32_t, InlineCallFrame*, int32_t); … … 125 128 EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState*, EncodedJSValue) WTF_INTERNAL; 126 129 EncodedJSValue DFG_OPERATION operationStrCat(ExecState*, void*, size_t) WTF_INTERNAL; 127 EncodedJSValue DFG_OPERATION operationNewArray(ExecState*, void*, size_t) WTF_INTERNAL;130 EncodedJSValue DFG_OPERATION operationNewArray(ExecState*, Structure*, void*, size_t) WTF_INTERNAL; 128 131 EncodedJSValue DFG_OPERATION operationNewArrayBuffer(ExecState*, size_t, size_t) WTF_INTERNAL; 132 EncodedJSValue DFG_OPERATION operationNewEmptyArray(ExecState*, Structure*) WTF_INTERNAL; 133 EncodedJSValue DFG_OPERATION operationNewArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL; 129 134 EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState*, void*) WTF_INTERNAL; 130 135 void DFG_OPERATION operationPutByValStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r120499 r121280 536 536 } 537 537 538 case NewArrayWithSize: { 539 changed |= setPrediction(SpecArray); 540 changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt); 541 break; 542 } 543 538 544 case NewArrayBuffer: { 539 545 changed |= setPrediction(SpecArray); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r120989 r121280 1245 1245 return appendCallWithExceptionCheckSetResult(operation, result); 1246 1246 } 1247 JITCompiler::Call callOperation(J_DFGOperation_ESt operation, GPRReg result, Structure* structure) 1248 { 1249 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure)); 1250 return appendCallWithExceptionCheckSetResult(operation, result); 1251 } 1252 JITCompiler::Call callOperation(J_DFGOperation_EStI operation, GPRReg result, Structure* structure, GPRReg arg2) 1253 { 1254 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2); 1255 return appendCallWithExceptionCheckSetResult(operation, result); 1256 } 1257 JITCompiler::Call callOperation(J_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size) 1258 { 1259 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size)); 1260 return appendCallWithExceptionCheckSetResult(operation, result); 1261 } 1247 1262 JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg result, void* pointer, size_t size) 1248 1263 { … … 1501 1516 { 1502 1517 m_jit.setupArgumentsWithExecState(arg1); 1518 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1519 } 1520 JITCompiler::Call callOperation(J_DFGOperation_ESt operation, GPRReg resultTag, GPRReg resultPayload, Structure* structure) 1521 { 1522 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure)); 1523 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1524 } 1525 JITCompiler::Call callOperation(J_DFGOperation_EStI operation, GPRReg resultTag, GPRReg resultPayload, Structure* structure, GPRReg arg2) 1526 { 1527 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2); 1528 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1529 } 1530 JITCompiler::Call callOperation(J_DFGOperation_EStPS operation, GPRReg resultTag, GPRReg resultPayload, Structure* structure, void* pointer, size_t size) 1531 { 1532 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size)); 1503 1533 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); 1504 1534 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r121243 r121280 2976 2976 } 2977 2977 2978 case StrCat: 2979 case NewArray: { 2980 // We really don't want to grow the register file just to do a StrCat or NewArray. 2981 // Say we have 50 functions on the stack that all have a StrCat in them that has 2982 // upwards of 10 operands. In the DFG this would mean that each one gets 2983 // some random virtual register, and then to do the StrCat we'd need a second 2984 // span of 10 operands just to have somewhere to copy the 10 operands to, where 2985 // they'd be contiguous and we could easily tell the C code how to find them. 2986 // Ugly! So instead we use the scratchBuffer infrastructure in JSGlobalData. That 2987 // way, those 50 functions will share the same scratchBuffer for offloading their 2988 // StrCat operands. It's about as good as we can do, unless we start doing 2989 // virtual register coalescing to ensure that operands to StrCat get spilled 2990 // in exactly the place where StrCat wants them, or else have the StrCat 2991 // refer to those operands' SetLocal instructions to force them to spill in 2992 // the right place. Basically, any way you cut it, the current approach 2993 // probably has the best balance of performance and sensibility in the sense 2994 // that it does not increase the complexity of the DFG JIT just to make StrCat 2995 // fast and pretty. 2996 2978 case StrCat: { 2997 2979 size_t scratchSize = sizeof(EncodedJSValue) * node.numChildren(); 2998 2980 ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(scratchSize); … … 3022 3004 GPRResult2 resultTag(this); 3023 3005 3024 callOperation(op == StrCat ? operationStrCat : operationNewArray, resultTag.gpr(), resultPayload.gpr(), static_cast<void *>(buffer), node.numChildren());3006 callOperation(operationStrCat, resultTag.gpr(), resultPayload.gpr(), static_cast<void *>(buffer), node.numChildren()); 3025 3007 3026 3008 if (scratchSize) { … … 3036 3018 } 3037 3019 3020 case NewArray: { 3021 if (!node.numChildren()) { 3022 flushRegisters(); 3023 GPRResult result(this); 3024 GPRResult2 resultTagIgnored(this); 3025 callOperation( 3026 operationNewEmptyArray, resultTagIgnored.gpr(), result.gpr(), 3027 m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure()); 3028 cellResult(result.gpr(), m_compileIndex); 3029 break; 3030 } 3031 3032 size_t scratchSize = sizeof(EncodedJSValue) * node.numChildren(); 3033 ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(scratchSize); 3034 EncodedJSValue* buffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0; 3035 3036 for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) { 3037 JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); 3038 GPRReg opTagGPR = operand.tagGPR(); 3039 GPRReg opPayloadGPR = operand.payloadGPR(); 3040 operand.use(); 3041 3042 m_jit.store32(opTagGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)); 3043 m_jit.store32(opPayloadGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); 3044 } 3045 3046 flushRegisters(); 3047 3048 if (scratchSize) { 3049 GPRTemporary scratch(this); 3050 3051 // Tell GC mark phase how much of the scratch buffer is active during call. 3052 m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr()); 3053 m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr()); 3054 } 3055 3056 GPRResult resultPayload(this); 3057 GPRResult2 resultTag(this); 3058 3059 callOperation( 3060 operationNewArray, resultTag.gpr(), resultPayload.gpr(), 3061 m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure(), 3062 static_cast<void *>(buffer), node.numChildren()); 3063 3064 if (scratchSize) { 3065 GPRTemporary scratch(this); 3066 3067 m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr()); 3068 m_jit.storePtr(TrustedImmPtr(0), scratch.gpr()); 3069 } 3070 3071 // FIXME: make the callOperation above explicitly return a cell result, or jitAssert the tag is a cell tag. 3072 cellResult(resultPayload.gpr(), m_compileIndex, UseChildrenCalledExplicitly); 3073 break; 3074 } 3075 3076 case NewArrayWithSize: { 3077 SpeculateStrictInt32Operand size(this, node.child1()); 3078 GPRReg sizeGPR = size.gpr(); 3079 flushRegisters(); 3080 GPRResult result(this); 3081 GPRResult2 resultTagIgnored(this); 3082 callOperation( 3083 operationNewArrayWithSize, resultTagIgnored.gpr(), result.gpr(), 3084 m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure(), sizeGPR); 3085 cellResult(result.gpr(), m_compileIndex); 3086 break; 3087 } 3088 3038 3089 case NewArrayBuffer: { 3039 3090 flushRegisters(); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r120989 r121280 3036 3036 } 3037 3037 3038 case StrCat:3039 3038 case NewArray: { 3040 // We really don't want to grow the register file just to do a StrCat or NewArray. 3041 // Say we have 50 functions on the stack that all have a StrCat in them that has 3042 // upwards of 10 operands. In the DFG this would mean that each one gets 3043 // some random virtual register, and then to do the StrCat we'd need a second 3044 // span of 10 operands just to have somewhere to copy the 10 operands to, where 3045 // they'd be contiguous and we could easily tell the C code how to find them. 3046 // Ugly! So instead we use the scratchBuffer infrastructure in JSGlobalData. That 3047 // way, those 50 functions will share the same scratchBuffer for offloading their 3048 // StrCat operands. It's about as good as we can do, unless we start doing 3049 // virtual register coalescing to ensure that operands to StrCat get spilled 3050 // in exactly the place where StrCat wants them, or else have the StrCat 3051 // refer to those operands' SetLocal instructions to force them to spill in 3052 // the right place. Basically, any way you cut it, the current approach 3053 // probably has the best balance of performance and sensibility in the sense 3054 // that it does not increase the complexity of the DFG JIT just to make StrCat 3055 // fast and pretty. 3056 3039 if (!node.numChildren()) { 3040 flushRegisters(); 3041 GPRResult result(this); 3042 callOperation( 3043 operationNewEmptyArray, result.gpr(), 3044 m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure()); 3045 cellResult(result.gpr(), m_compileIndex); 3046 break; 3047 } 3048 3057 3049 size_t scratchSize = sizeof(EncodedJSValue) * node.numChildren(); 3058 3050 ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(scratchSize); … … 3079 3071 GPRResult result(this); 3080 3072 3081 callOperation(op == StrCat ? operationStrCat : operationNewArray, result.gpr(), static_cast<void *>(buffer), node.numChildren()); 3073 callOperation( 3074 operationNewArray, result.gpr(), 3075 m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure(), 3076 static_cast<void*>(buffer), node.numChildren()); 3077 3078 if (scratchSize) { 3079 GPRTemporary scratch(this); 3080 3081 m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr()); 3082 m_jit.storePtr(TrustedImmPtr(0), scratch.gpr()); 3083 } 3084 3085 cellResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly); 3086 break; 3087 } 3088 3089 case NewArrayWithSize: { 3090 SpeculateStrictInt32Operand size(this, node.child1()); 3091 GPRReg sizeGPR = size.gpr(); 3092 flushRegisters(); 3093 GPRResult result(this); 3094 callOperation(operationNewArrayWithSize, result.gpr(), m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure(), sizeGPR); 3095 cellResult(result.gpr(), m_compileIndex); 3096 break; 3097 } 3098 3099 case StrCat: { 3100 size_t scratchSize = sizeof(EncodedJSValue) * node.numChildren(); 3101 ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(scratchSize); 3102 EncodedJSValue* buffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0; 3103 3104 for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) { 3105 JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); 3106 GPRReg opGPR = operand.gpr(); 3107 operand.use(); 3108 3109 m_jit.storePtr(opGPR, buffer + operandIdx); 3110 } 3111 3112 flushRegisters(); 3113 3114 if (scratchSize) { 3115 GPRTemporary scratch(this); 3116 3117 // Tell GC mark phase how much of the scratch buffer is active during call. 3118 m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr()); 3119 m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr()); 3120 } 3121 3122 GPRResult result(this); 3123 3124 callOperation(operationStrCat, result.gpr(), static_cast<void *>(buffer), node.numChildren()); 3082 3125 3083 3126 if (scratchSize) { -
trunk/Source/JavaScriptCore/runtime/JSArray.h
r116828 r121280 381 381 return size; 382 382 } 383 384 inline JSArray* constructArray(ExecState* exec, Structure* arrayStructure, const ArgList& values) 385 { 386 JSGlobalData& globalData = exec->globalData(); 387 unsigned length = values.size(); 388 JSArray* array = JSArray::tryCreateUninitialized(globalData, arrayStructure, length); 389 390 // FIXME: we should probably throw an out of memory error here, but 391 // when making this change we should check that all clients of this 392 // function will correctly handle an exception being thrown from here. 393 if (!array) 394 CRASH(); 395 396 for (unsigned i = 0; i < length; ++i) 397 array->initializeIndex(globalData, i, values.at(i)); 398 array->completeInitialization(length); 399 return array; 400 } 383 401 384 } // namespace JSC 402 inline JSArray* constructArray(ExecState* exec, Structure* arrayStructure, const JSValue* values, unsigned length) 403 { 404 JSGlobalData& globalData = exec->globalData(); 405 JSArray* array = JSArray::tryCreateUninitialized(globalData, arrayStructure, length); 406 407 // FIXME: we should probably throw an out of memory error here, but 408 // when making this change we should check that all clients of this 409 // function will correctly handle an exception being thrown from here. 410 if (!array) 411 CRASH(); 412 413 for (unsigned i = 0; i < length; ++i) 414 array->initializeIndex(globalData, i, values[i]); 415 array->completeInitialization(length); 416 return array; 417 } 418 419 } // namespace JSC 385 420 386 421 #endif // JSArray_h -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r121215 r121280 446 446 return constructEmptyArray(exec, exec->lexicalGlobalObject(), initialLength); 447 447 } 448 448 449 449 inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const ArgList& values) 450 450 { 451 JSGlobalData& globalData = exec->globalData(); 452 unsigned length = values.size(); 453 JSArray* array = JSArray::tryCreateUninitialized(globalData, globalObject->arrayStructure(), length); 454 455 // FIXME: we should probably throw an out of memory error here, but 456 // when making this change we should check that all clients of this 457 // function will correctly handle an exception being thrown from here. 458 if (!array) 459 CRASH(); 460 461 for (unsigned i = 0; i < length; ++i) 462 array->initializeIndex(globalData, i, values.at(i)); 463 array->completeInitialization(length); 464 return array; 451 return constructArray(exec, globalObject->arrayStructure(), values); 465 452 } 466 453 … … 472 459 inline JSArray* constructArray(ExecState* exec, JSGlobalObject* globalObject, const JSValue* values, unsigned length) 473 460 { 474 JSGlobalData& globalData = exec->globalData(); 475 JSArray* array = JSArray::tryCreateUninitialized(globalData, globalObject->arrayStructure(), length); 476 477 // FIXME: we should probably throw an out of memory error here, but 478 // when making this change we should check that all clients of this 479 // function will correctly handle an exception being thrown from here. 480 if (!array) 481 CRASH(); 482 483 for (unsigned i = 0; i < length; ++i) 484 array->initializeIndex(globalData, i, values[i]); 485 array->completeInitialization(length); 486 return array; 461 return constructArray(exec, globalObject->arrayStructure(), values, length); 487 462 } 488 463
Note:
See TracChangeset
for help on using the changeset viewer.