| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 __ vmov(double_result, 1.0, scratch); | 1344 __ vmov(double_result, 1.0, scratch); |
| 1345 __ vsqrt(double_scratch, double_scratch); | 1345 __ vsqrt(double_scratch, double_scratch); |
| 1346 __ vdiv(double_result, double_result, double_scratch); | 1346 __ vdiv(double_result, double_result, double_scratch); |
| 1347 __ jmp(&done); | 1347 __ jmp(&done); |
| 1348 } | 1348 } |
| 1349 | 1349 |
| 1350 __ push(lr); | 1350 __ push(lr); |
| 1351 { | 1351 { |
| 1352 AllowExternalCallThatCantCauseGC scope(masm); | 1352 AllowExternalCallThatCantCauseGC scope(masm); |
| 1353 __ PrepareCallCFunction(0, 2, scratch); | 1353 __ PrepareCallCFunction(0, 2, scratch); |
| 1354 __ SetCallCDoubleArguments(double_base, double_exponent); | 1354 __ MovToFloatParameters(double_base, double_exponent); |
| 1355 __ CallCFunction( | 1355 __ CallCFunction( |
| 1356 ExternalReference::power_double_double_function(masm->isolate()), | 1356 ExternalReference::power_double_double_function(masm->isolate()), |
| 1357 0, 2); | 1357 0, 2); |
| 1358 } | 1358 } |
| 1359 __ pop(lr); | 1359 __ pop(lr); |
| 1360 __ GetCFunctionDoubleResult(double_result); | 1360 __ MovFromFloatResult(double_result); |
| 1361 __ jmp(&done); | 1361 __ jmp(&done); |
| 1362 | 1362 |
| 1363 __ bind(&int_exponent_convert); | 1363 __ bind(&int_exponent_convert); |
| 1364 __ vcvt_u32_f64(single_scratch, double_exponent); | 1364 __ vcvt_u32_f64(single_scratch, double_exponent); |
| 1365 __ vmov(scratch, single_scratch); | 1365 __ vmov(scratch, single_scratch); |
| 1366 } | 1366 } |
| 1367 | 1367 |
| 1368 // Calculate power with integer exponent. | 1368 // Calculate power with integer exponent. |
| 1369 __ bind(&int_exponent); | 1369 __ bind(&int_exponent); |
| 1370 | 1370 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1418 __ vstr(double_result, | 1418 __ vstr(double_result, |
| 1419 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); | 1419 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); |
| 1420 ASSERT(heapnumber.is(r0)); | 1420 ASSERT(heapnumber.is(r0)); |
| 1421 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); | 1421 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); |
| 1422 __ Ret(2); | 1422 __ Ret(2); |
| 1423 } else { | 1423 } else { |
| 1424 __ push(lr); | 1424 __ push(lr); |
| 1425 { | 1425 { |
| 1426 AllowExternalCallThatCantCauseGC scope(masm); | 1426 AllowExternalCallThatCantCauseGC scope(masm); |
| 1427 __ PrepareCallCFunction(0, 2, scratch); | 1427 __ PrepareCallCFunction(0, 2, scratch); |
| 1428 __ SetCallCDoubleArguments(double_base, double_exponent); | 1428 __ MovToFloatParameters(double_base, double_exponent); |
| 1429 __ CallCFunction( | 1429 __ CallCFunction( |
| 1430 ExternalReference::power_double_double_function(masm->isolate()), | 1430 ExternalReference::power_double_double_function(masm->isolate()), |
| 1431 0, 2); | 1431 0, 2); |
| 1432 } | 1432 } |
| 1433 __ pop(lr); | 1433 __ pop(lr); |
| 1434 __ GetCFunctionDoubleResult(double_result); | 1434 __ MovFromFloatResult(double_result); |
| 1435 | 1435 |
| 1436 __ bind(&done); | 1436 __ bind(&done); |
| 1437 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); | 1437 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); |
| 1438 __ Ret(); | 1438 __ Ret(); |
| 1439 } | 1439 } |
| 1440 } | 1440 } |
| 1441 | 1441 |
| 1442 | 1442 |
| 1443 bool CEntryStub::NeedsImmovableCode() { | 1443 bool CEntryStub::NeedsImmovableCode() { |
| 1444 return true; | 1444 return true; |
| (...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3175 | 3175 |
| 3176 __ bind(&done); | 3176 __ bind(&done); |
| 3177 } | 3177 } |
| 3178 | 3178 |
| 3179 | 3179 |
| 3180 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3180 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| 3181 // r1 : the function to call | 3181 // r1 : the function to call |
| 3182 // r2 : cache cell for call target | 3182 // r2 : cache cell for call target |
| 3183 Label slow, non_function; | 3183 Label slow, non_function; |
| 3184 | 3184 |
| 3185 // The receiver might implicitly be the global object. This is | |
| 3186 // indicated by passing the hole as the receiver to the call | |
| 3187 // function stub. | |
| 3188 if (ReceiverMightBeImplicit()) { | |
| 3189 Label call; | |
| 3190 // Get the receiver from the stack. | |
| 3191 // function, receiver [, arguments] | |
| 3192 __ ldr(r4, MemOperand(sp, argc_ * kPointerSize)); | |
| 3193 // Call as function is indicated with the hole. | |
| 3194 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | |
| 3195 __ b(ne, &call); | |
| 3196 // Patch the receiver on the stack with the global receiver object. | |
| 3197 __ ldr(r3, | |
| 3198 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | |
| 3199 __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalReceiverOffset)); | |
| 3200 __ str(r3, MemOperand(sp, argc_ * kPointerSize)); | |
| 3201 __ bind(&call); | |
| 3202 } | |
| 3203 | |
| 3204 // Check that the function is really a JavaScript function. | 3185 // Check that the function is really a JavaScript function. |
| 3205 // r1: pushed function (to be verified) | 3186 // r1: pushed function (to be verified) |
| 3206 __ JumpIfSmi(r1, &non_function); | 3187 __ JumpIfSmi(r1, &non_function); |
| 3207 // Get the map of the function object. | 3188 |
| 3189 // Goto slow case if we do not have a function. |
| 3208 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | 3190 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); |
| 3209 __ b(ne, &slow); | 3191 __ b(ne, &slow); |
| 3210 | 3192 |
| 3211 if (RecordCallTarget()) { | 3193 if (RecordCallTarget()) { |
| 3212 GenerateRecordCallTarget(masm); | 3194 GenerateRecordCallTarget(masm); |
| 3213 } | 3195 } |
| 3214 | 3196 |
| 3215 // Fast-case: Invoke the function now. | 3197 // Fast-case: Invoke the function now. |
| 3216 // r1: pushed function | 3198 // r1: pushed function |
| 3217 ParameterCount actual(argc_); | 3199 ParameterCount actual(argc_); |
| 3218 | 3200 |
| 3219 if (ReceiverMightBeImplicit()) { | |
| 3220 Label call_as_function; | |
| 3221 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | |
| 3222 __ b(eq, &call_as_function); | |
| 3223 __ InvokeFunction(r1, | |
| 3224 actual, | |
| 3225 JUMP_FUNCTION, | |
| 3226 NullCallWrapper(), | |
| 3227 CALL_AS_METHOD); | |
| 3228 __ bind(&call_as_function); | |
| 3229 } | |
| 3230 __ InvokeFunction(r1, | 3201 __ InvokeFunction(r1, |
| 3231 actual, | 3202 actual, |
| 3232 JUMP_FUNCTION, | 3203 JUMP_FUNCTION, |
| 3233 NullCallWrapper(), | 3204 NullCallWrapper(), |
| 3234 CALL_AS_FUNCTION); | 3205 CALL_AS_FUNCTION); |
| 3235 | 3206 |
| 3236 // Slow-case: Non-function called. | 3207 // Slow-case: Non-function called. |
| 3237 __ bind(&slow); | 3208 __ bind(&slow); |
| 3238 if (RecordCallTarget()) { | 3209 if (RecordCallTarget()) { |
| 3239 // If there is a call target cache, mark it megamorphic in the | 3210 // If there is a call target cache, mark it megamorphic in the |
| 3240 // non-function case. MegamorphicSentinel is an immortal immovable | 3211 // non-function case. MegamorphicSentinel is an immortal immovable |
| 3241 // object (undefined) so no write barrier is needed. | 3212 // object (undefined) so no write barrier is needed. |
| 3242 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), | 3213 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), |
| 3243 masm->isolate()->heap()->undefined_value()); | 3214 masm->isolate()->heap()->undefined_value()); |
| 3244 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 3215 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 3245 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); | 3216 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); |
| 3246 } | 3217 } |
| 3247 // Check for function proxy. | 3218 // Check for function proxy. |
| 3248 __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE)); | 3219 __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE)); |
| 3249 __ b(ne, &non_function); | 3220 __ b(ne, &non_function); |
| 3250 __ push(r1); // put proxy as additional argument | 3221 __ push(r1); // put proxy as additional argument |
| 3251 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32)); | 3222 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32)); |
| 3252 __ mov(r2, Operand::Zero()); | 3223 __ mov(r2, Operand::Zero()); |
| 3253 __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY); | 3224 __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY); |
| 3254 __ SetCallKind(r5, CALL_AS_METHOD); | 3225 __ SetCallKind(r5, CALL_AS_FUNCTION); |
| 3255 { | 3226 { |
| 3256 Handle<Code> adaptor = | 3227 Handle<Code> adaptor = |
| 3257 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 3228 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
| 3258 __ Jump(adaptor, RelocInfo::CODE_TARGET); | 3229 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
| 3259 } | 3230 } |
| 3260 | 3231 |
| 3261 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 3232 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
| 3262 // of the original receiver from the call site). | 3233 // of the original receiver from the call site). |
| 3263 __ bind(&non_function); | 3234 __ bind(&non_function); |
| 3264 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); | 3235 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); |
| 3265 __ mov(r0, Operand(argc_)); // Set up the number of arguments. | 3236 __ mov(r0, Operand(argc_)); // Set up the number of arguments. |
| 3266 __ mov(r2, Operand::Zero()); | 3237 __ mov(r2, Operand::Zero()); |
| 3267 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 3238 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
| 3268 __ SetCallKind(r5, CALL_AS_METHOD); | 3239 __ SetCallKind(r5, CALL_AS_FUNCTION); |
| 3269 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 3240 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 3270 RelocInfo::CODE_TARGET); | 3241 RelocInfo::CODE_TARGET); |
| 3271 } | 3242 } |
| 3272 | 3243 |
| 3273 | 3244 |
| 3274 void CallConstructStub::Generate(MacroAssembler* masm) { | 3245 void CallConstructStub::Generate(MacroAssembler* masm) { |
| 3275 // r0 : number of arguments | 3246 // r0 : number of arguments |
| 3276 // r1 : the function to call | 3247 // r1 : the function to call |
| 3277 // r2 : cache cell for call target | 3248 // r2 : cache cell for call target |
| 3278 Label slow, non_function_call; | 3249 Label slow, non_function_call; |
| (...skipping 2250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5529 | 5500 |
| 5530 // Also pop pc to get Ret(0). | 5501 // Also pop pc to get Ret(0). |
| 5531 __ ldm(ia_w, sp, kSavedRegs | pc.bit()); | 5502 __ ldm(ia_w, sp, kSavedRegs | pc.bit()); |
| 5532 } | 5503 } |
| 5533 | 5504 |
| 5534 | 5505 |
| 5535 template<class T> | 5506 template<class T> |
| 5536 static void CreateArrayDispatch(MacroAssembler* masm, | 5507 static void CreateArrayDispatch(MacroAssembler* masm, |
| 5537 AllocationSiteOverrideMode mode) { | 5508 AllocationSiteOverrideMode mode) { |
| 5538 if (mode == DISABLE_ALLOCATION_SITES) { | 5509 if (mode == DISABLE_ALLOCATION_SITES) { |
| 5539 T stub(GetInitialFastElementsKind(), | 5510 T stub(GetInitialFastElementsKind(), mode); |
| 5540 CONTEXT_CHECK_REQUIRED, | |
| 5541 mode); | |
| 5542 __ TailCallStub(&stub); | 5511 __ TailCallStub(&stub); |
| 5543 } else if (mode == DONT_OVERRIDE) { | 5512 } else if (mode == DONT_OVERRIDE) { |
| 5544 int last_index = GetSequenceIndexFromFastElementsKind( | 5513 int last_index = GetSequenceIndexFromFastElementsKind( |
| 5545 TERMINAL_FAST_ELEMENTS_KIND); | 5514 TERMINAL_FAST_ELEMENTS_KIND); |
| 5546 for (int i = 0; i <= last_index; ++i) { | 5515 for (int i = 0; i <= last_index; ++i) { |
| 5547 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 5516 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 5548 __ cmp(r3, Operand(kind)); | 5517 __ cmp(r3, Operand(kind)); |
| 5549 T stub(kind); | 5518 T stub(kind); |
| 5550 __ TailCallStub(&stub, eq); | 5519 __ TailCallStub(&stub, eq); |
| 5551 } | 5520 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 5582 // look at the first argument | 5551 // look at the first argument |
| 5583 __ ldr(r5, MemOperand(sp, 0)); | 5552 __ ldr(r5, MemOperand(sp, 0)); |
| 5584 __ cmp(r5, Operand::Zero()); | 5553 __ cmp(r5, Operand::Zero()); |
| 5585 __ b(eq, &normal_sequence); | 5554 __ b(eq, &normal_sequence); |
| 5586 | 5555 |
| 5587 if (mode == DISABLE_ALLOCATION_SITES) { | 5556 if (mode == DISABLE_ALLOCATION_SITES) { |
| 5588 ElementsKind initial = GetInitialFastElementsKind(); | 5557 ElementsKind initial = GetInitialFastElementsKind(); |
| 5589 ElementsKind holey_initial = GetHoleyElementsKind(initial); | 5558 ElementsKind holey_initial = GetHoleyElementsKind(initial); |
| 5590 | 5559 |
| 5591 ArraySingleArgumentConstructorStub stub_holey(holey_initial, | 5560 ArraySingleArgumentConstructorStub stub_holey(holey_initial, |
| 5592 CONTEXT_CHECK_REQUIRED, | |
| 5593 DISABLE_ALLOCATION_SITES); | 5561 DISABLE_ALLOCATION_SITES); |
| 5594 __ TailCallStub(&stub_holey); | 5562 __ TailCallStub(&stub_holey); |
| 5595 | 5563 |
| 5596 __ bind(&normal_sequence); | 5564 __ bind(&normal_sequence); |
| 5597 ArraySingleArgumentConstructorStub stub(initial, | 5565 ArraySingleArgumentConstructorStub stub(initial, |
| 5598 CONTEXT_CHECK_REQUIRED, | |
| 5599 DISABLE_ALLOCATION_SITES); | 5566 DISABLE_ALLOCATION_SITES); |
| 5600 __ TailCallStub(&stub); | 5567 __ TailCallStub(&stub); |
| 5601 } else if (mode == DONT_OVERRIDE) { | 5568 } else if (mode == DONT_OVERRIDE) { |
| 5602 // We are going to create a holey array, but our kind is non-holey. | 5569 // We are going to create a holey array, but our kind is non-holey. |
| 5603 // Fix kind and retry (only if we have an allocation site in the cell). | 5570 // Fix kind and retry (only if we have an allocation site in the cell). |
| 5604 __ add(r3, r3, Operand(1)); | 5571 __ add(r3, r3, Operand(1)); |
| 5605 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); | 5572 __ ldr(r5, FieldMemOperand(r2, Cell::kValueOffset)); |
| 5606 | 5573 |
| 5607 if (FLAG_debug_code) { | 5574 if (FLAG_debug_code) { |
| 5608 __ ldr(r5, FieldMemOperand(r5, 0)); | 5575 __ ldr(r5, FieldMemOperand(r5, 0)); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5632 // If we reached this point there is a problem. | 5599 // If we reached this point there is a problem. |
| 5633 __ Abort(kUnexpectedElementsKindInArrayConstructor); | 5600 __ Abort(kUnexpectedElementsKindInArrayConstructor); |
| 5634 } else { | 5601 } else { |
| 5635 UNREACHABLE(); | 5602 UNREACHABLE(); |
| 5636 } | 5603 } |
| 5637 } | 5604 } |
| 5638 | 5605 |
| 5639 | 5606 |
| 5640 template<class T> | 5607 template<class T> |
| 5641 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { | 5608 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { |
| 5642 ElementsKind initial_kind = GetInitialFastElementsKind(); | |
| 5643 ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind); | |
| 5644 | |
| 5645 int to_index = GetSequenceIndexFromFastElementsKind( | 5609 int to_index = GetSequenceIndexFromFastElementsKind( |
| 5646 TERMINAL_FAST_ELEMENTS_KIND); | 5610 TERMINAL_FAST_ELEMENTS_KIND); |
| 5647 for (int i = 0; i <= to_index; ++i) { | 5611 for (int i = 0; i <= to_index; ++i) { |
| 5648 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 5612 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
| 5649 T stub(kind); | 5613 T stub(kind); |
| 5650 stub.GetCode(isolate); | 5614 stub.GetCode(isolate); |
| 5651 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE || | 5615 if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { |
| 5652 (!FLAG_track_allocation_sites && | 5616 T stub1(kind, DISABLE_ALLOCATION_SITES); |
| 5653 (kind == initial_kind || kind == initial_holey_kind))) { | |
| 5654 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); | |
| 5655 stub1.GetCode(isolate); | 5617 stub1.GetCode(isolate); |
| 5656 } | 5618 } |
| 5657 } | 5619 } |
| 5658 } | 5620 } |
| 5659 | 5621 |
| 5660 | 5622 |
| 5661 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { | 5623 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { |
| 5662 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( | 5624 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( |
| 5663 isolate); | 5625 isolate); |
| 5664 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( | 5626 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5838 __ bind(&fast_elements_case); | 5800 __ bind(&fast_elements_case); |
| 5839 GenerateCase(masm, FAST_ELEMENTS); | 5801 GenerateCase(masm, FAST_ELEMENTS); |
| 5840 } | 5802 } |
| 5841 | 5803 |
| 5842 | 5804 |
| 5843 #undef __ | 5805 #undef __ |
| 5844 | 5806 |
| 5845 } } // namespace v8::internal | 5807 } } // namespace v8::internal |
| 5846 | 5808 |
| 5847 #endif // V8_TARGET_ARCH_ARM | 5809 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |