| 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 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 | 483 |
| 484 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { | 484 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { |
| 485 // Update the static counter each time a new code stub is generated. | 485 // Update the static counter each time a new code stub is generated. |
| 486 Isolate* isolate = masm->isolate(); | 486 Isolate* isolate = masm->isolate(); |
| 487 isolate->counters()->code_stubs()->Increment(); | 487 isolate->counters()->code_stubs()->Increment(); |
| 488 | 488 |
| 489 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); | 489 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); |
| 490 int param_count = descriptor->register_param_count_; | 490 int param_count = descriptor->register_param_count_; |
| 491 { | 491 { |
| 492 // Call the runtime system in a fresh internal frame. | 492 // Call the runtime system in a fresh internal frame. |
| 493 FrameScope scope(masm, StackFrame::INTERNAL); | 493 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 494 ASSERT(descriptor->register_param_count_ == 0 || | 494 ASSERT(descriptor->register_param_count_ == 0 || |
| 495 r0.is(descriptor->register_params_[param_count - 1])); | 495 r0.is(descriptor->register_params_[param_count - 1])); |
| 496 // Push arguments | 496 // Push arguments |
| 497 for (int i = 0; i < param_count; ++i) { | 497 for (int i = 0; i < param_count; ++i) { |
| 498 __ push(descriptor->register_params_[i]); | 498 __ push(descriptor->register_params_[i]); |
| 499 } | 499 } |
| 500 ExternalReference miss = descriptor->miss_handler(); | 500 ExternalReference miss = descriptor->miss_handler(); |
| 501 __ CallExternalReference(miss, descriptor->register_param_count_); | 501 __ CallExternalReference(miss, descriptor->register_param_count_); |
| 502 } | 502 } |
| 503 | 503 |
| (...skipping 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1599 | 1599 |
| 1600 // Retrieve the pending exception. | 1600 // Retrieve the pending exception. |
| 1601 __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 1601 __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
| 1602 isolate))); | 1602 isolate))); |
| 1603 __ ldr(r0, MemOperand(ip)); | 1603 __ ldr(r0, MemOperand(ip)); |
| 1604 | 1604 |
| 1605 // See if we just retrieved an OOM exception. | 1605 // See if we just retrieved an OOM exception. |
| 1606 JumpIfOOM(masm, r0, ip, throw_out_of_memory_exception); | 1606 JumpIfOOM(masm, r0, ip, throw_out_of_memory_exception); |
| 1607 | 1607 |
| 1608 // Clear the pending exception. | 1608 // Clear the pending exception. |
| 1609 __ mov(r3, Operand(isolate->factory()->the_hole_value())); | 1609 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); |
| 1610 __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 1610 __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
| 1611 isolate))); | 1611 isolate))); |
| 1612 __ str(r3, MemOperand(ip)); | 1612 __ str(r3, MemOperand(ip)); |
| 1613 | 1613 |
| 1614 // Special handling of termination exceptions which are uncatchable | 1614 // Special handling of termination exceptions which are uncatchable |
| 1615 // by javascript code. | 1615 // by javascript code. |
| 1616 __ cmp(r0, Operand(isolate->factory()->termination_exception())); | 1616 __ LoadRoot(r3, Heap::kTerminationExceptionRootIndex); |
| 1617 __ cmp(r0, r3); |
| 1617 __ b(eq, throw_termination_exception); | 1618 __ b(eq, throw_termination_exception); |
| 1618 | 1619 |
| 1619 // Handle normal exception. | 1620 // Handle normal exception. |
| 1620 __ jmp(throw_normal_exception); | 1621 __ jmp(throw_normal_exception); |
| 1621 | 1622 |
| 1622 __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying | 1623 __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying |
| 1623 } | 1624 } |
| 1624 | 1625 |
| 1625 | 1626 |
| 1626 void CEntryStub::Generate(MacroAssembler* masm) { | 1627 void CEntryStub::Generate(MacroAssembler* masm) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1638 // NOTE: Invocations of builtins may return failure objects | 1639 // NOTE: Invocations of builtins may return failure objects |
| 1639 // instead of a proper result. The builtin entry handles | 1640 // instead of a proper result. The builtin entry handles |
| 1640 // this by performing a garbage collection and retrying the | 1641 // this by performing a garbage collection and retrying the |
| 1641 // builtin once. | 1642 // builtin once. |
| 1642 | 1643 |
| 1643 // Compute the argv pointer in a callee-saved register. | 1644 // Compute the argv pointer in a callee-saved register. |
| 1644 __ add(r6, sp, Operand(r0, LSL, kPointerSizeLog2)); | 1645 __ add(r6, sp, Operand(r0, LSL, kPointerSizeLog2)); |
| 1645 __ sub(r6, r6, Operand(kPointerSize)); | 1646 __ sub(r6, r6, Operand(kPointerSize)); |
| 1646 | 1647 |
| 1647 // Enter the exit frame that transitions from JavaScript to C++. | 1648 // Enter the exit frame that transitions from JavaScript to C++. |
| 1648 FrameScope scope(masm, StackFrame::MANUAL); | 1649 FrameAndConstantPoolScope scope(masm, StackFrame::MANUAL); |
| 1649 __ EnterExitFrame(save_doubles_); | 1650 __ EnterExitFrame(save_doubles_); |
| 1650 | 1651 |
| 1651 // Set up argc and the builtin function in callee-saved registers. | 1652 // Set up argc and the builtin function in callee-saved registers. |
| 1652 __ mov(r4, Operand(r0)); | 1653 __ mov(r4, Operand(r0)); |
| 1653 __ mov(r5, Operand(r1)); | 1654 __ mov(r5, Operand(r1)); |
| 1654 | 1655 |
| 1655 // r4: number of arguments (C callee-saved) | 1656 // r4: number of arguments (C callee-saved) |
| 1656 // r5: pointer to builtin function (C callee-saved) | 1657 // r5: pointer to builtin function (C callee-saved) |
| 1657 // r6: pointer to first argument (C callee-saved) | 1658 // r6: pointer to first argument (C callee-saved) |
| 1658 | 1659 |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2051 | 2052 |
| 2052 // Slow-case. Tail call builtin. | 2053 // Slow-case. Tail call builtin. |
| 2053 __ bind(&slow); | 2054 __ bind(&slow); |
| 2054 if (!ReturnTrueFalseObject()) { | 2055 if (!ReturnTrueFalseObject()) { |
| 2055 if (HasArgsInRegisters()) { | 2056 if (HasArgsInRegisters()) { |
| 2056 __ Push(r0, r1); | 2057 __ Push(r0, r1); |
| 2057 } | 2058 } |
| 2058 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 2059 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 2059 } else { | 2060 } else { |
| 2060 { | 2061 { |
| 2061 FrameScope scope(masm, StackFrame::INTERNAL); | 2062 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 2062 __ Push(r0, r1); | 2063 __ Push(r0, r1); |
| 2063 __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION); | 2064 __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION); |
| 2064 } | 2065 } |
| 2065 __ cmp(r0, Operand::Zero()); | 2066 __ cmp(r0, Operand::Zero()); |
| 2066 __ LoadRoot(r0, Heap::kTrueValueRootIndex, eq); | 2067 __ LoadRoot(r0, Heap::kTrueValueRootIndex, eq); |
| 2067 __ LoadRoot(r0, Heap::kFalseValueRootIndex, ne); | 2068 __ LoadRoot(r0, Heap::kFalseValueRootIndex, ne); |
| 2068 __ Ret(HasArgsInRegisters() ? 0 : 2); | 2069 __ Ret(HasArgsInRegisters() ? 0 : 2); |
| 2069 } | 2070 } |
| 2070 } | 2071 } |
| 2071 | 2072 |
| (...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3060 // indicate the ElementsKind if function is the Array constructor. | 3061 // indicate the ElementsKind if function is the Array constructor. |
| 3061 __ bind(&initialize); | 3062 __ bind(&initialize); |
| 3062 // Make sure the function is the Array() function | 3063 // Make sure the function is the Array() function |
| 3063 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); | 3064 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); |
| 3064 __ cmp(r1, r4); | 3065 __ cmp(r1, r4); |
| 3065 __ b(ne, ¬_array_function); | 3066 __ b(ne, ¬_array_function); |
| 3066 | 3067 |
| 3067 // The target function is the Array constructor, | 3068 // The target function is the Array constructor, |
| 3068 // Create an AllocationSite if we don't already have it, store it in the slot. | 3069 // Create an AllocationSite if we don't already have it, store it in the slot. |
| 3069 { | 3070 { |
| 3070 FrameScope scope(masm, StackFrame::INTERNAL); | 3071 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 3071 | 3072 |
| 3072 // Arguments register must be smi-tagged to call out. | 3073 // Arguments register must be smi-tagged to call out. |
| 3073 __ SmiTag(r0); | 3074 __ SmiTag(r0); |
| 3074 __ Push(r3, r2, r1, r0); | 3075 __ Push(r3, r2, r1, r0); |
| 3075 | 3076 |
| 3076 CreateAllocationSiteStub create_stub; | 3077 CreateAllocationSiteStub create_stub; |
| 3077 __ CallStub(&create_stub); | 3078 __ CallStub(&create_stub); |
| 3078 | 3079 |
| 3079 __ Pop(r3, r2, r1, r0); | 3080 __ Pop(r3, r2, r1, r0); |
| 3080 __ SmiUntag(r0); | 3081 __ SmiUntag(r0); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3182 __ mov(r0, Operand(argc_)); // Set up the number of arguments. | 3183 __ mov(r0, Operand(argc_)); // Set up the number of arguments. |
| 3183 __ mov(r2, Operand::Zero()); | 3184 __ mov(r2, Operand::Zero()); |
| 3184 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION); | 3185 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION); |
| 3185 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 3186 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 3186 RelocInfo::CODE_TARGET); | 3187 RelocInfo::CODE_TARGET); |
| 3187 } | 3188 } |
| 3188 | 3189 |
| 3189 if (CallAsMethod()) { | 3190 if (CallAsMethod()) { |
| 3190 __ bind(&wrap); | 3191 __ bind(&wrap); |
| 3191 // Wrap the receiver and patch it back onto the stack. | 3192 // Wrap the receiver and patch it back onto the stack. |
| 3192 { FrameScope frame_scope(masm, StackFrame::INTERNAL); | 3193 { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); |
| 3193 __ Push(r1, r3); | 3194 __ Push(r1, r3); |
| 3194 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 3195 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
| 3195 __ pop(r1); | 3196 __ pop(r1); |
| 3196 } | 3197 } |
| 3197 __ str(r0, MemOperand(sp, argc_ * kPointerSize)); | 3198 __ str(r0, MemOperand(sp, argc_ * kPointerSize)); |
| 3198 __ jmp(&cont); | 3199 __ jmp(&cont); |
| 3199 } | 3200 } |
| 3200 } | 3201 } |
| 3201 | 3202 |
| 3202 | 3203 |
| (...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4466 } | 4467 } |
| 4467 | 4468 |
| 4468 | 4469 |
| 4469 | 4470 |
| 4470 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 4471 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { |
| 4471 { | 4472 { |
| 4472 // Call the runtime system in a fresh internal frame. | 4473 // Call the runtime system in a fresh internal frame. |
| 4473 ExternalReference miss = | 4474 ExternalReference miss = |
| 4474 ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate()); | 4475 ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate()); |
| 4475 | 4476 |
| 4476 FrameScope scope(masm, StackFrame::INTERNAL); | 4477 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 4477 __ Push(r1, r0); | 4478 __ Push(r1, r0); |
| 4478 __ Push(lr, r1, r0); | 4479 __ Push(lr, r1, r0); |
| 4479 __ mov(ip, Operand(Smi::FromInt(op_))); | 4480 __ mov(ip, Operand(Smi::FromInt(op_))); |
| 4480 __ push(ip); | 4481 __ push(ip); |
| 4481 __ CallExternalReference(miss, 3); | 4482 __ CallExternalReference(miss, 3); |
| 4482 // Compute the entry point of the rewritten stub. | 4483 // Compute the entry point of the rewritten stub. |
| 4483 __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 4484 __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 4484 // Restore registers. | 4485 // Restore registers. |
| 4485 __ pop(lr); | 4486 __ pop(lr); |
| 4486 __ Pop(r1, r0); | 4487 __ Pop(r1, r0); |
| (...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5483 // holder | 5484 // holder |
| 5484 __ push(holder); | 5485 __ push(holder); |
| 5485 | 5486 |
| 5486 // Prepare arguments. | 5487 // Prepare arguments. |
| 5487 __ mov(scratch, sp); | 5488 __ mov(scratch, sp); |
| 5488 | 5489 |
| 5489 // Allocate the v8::Arguments structure in the arguments' space since | 5490 // Allocate the v8::Arguments structure in the arguments' space since |
| 5490 // it's not controlled by GC. | 5491 // it's not controlled by GC. |
| 5491 const int kApiStackSpace = 4; | 5492 const int kApiStackSpace = 4; |
| 5492 | 5493 |
| 5493 FrameScope frame_scope(masm, StackFrame::MANUAL); | 5494 FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL); |
| 5494 __ EnterExitFrame(false, kApiStackSpace); | 5495 __ EnterExitFrame(false, kApiStackSpace); |
| 5495 | 5496 |
| 5496 ASSERT(!api_function_address.is(r0) && !scratch.is(r0)); | 5497 ASSERT(!api_function_address.is(r0) && !scratch.is(r0)); |
| 5497 // r0 = FunctionCallbackInfo& | 5498 // r0 = FunctionCallbackInfo& |
| 5498 // Arguments is after the return address. | 5499 // Arguments is after the return address. |
| 5499 __ add(r0, sp, Operand(1 * kPointerSize)); | 5500 __ add(r0, sp, Operand(1 * kPointerSize)); |
| 5500 // FunctionCallbackInfo::implicit_args_ | 5501 // FunctionCallbackInfo::implicit_args_ |
| 5501 __ str(scratch, MemOperand(r0, 0 * kPointerSize)); | 5502 __ str(scratch, MemOperand(r0, 0 * kPointerSize)); |
| 5502 // FunctionCallbackInfo::values_ | 5503 // FunctionCallbackInfo::values_ |
| 5503 __ add(ip, scratch, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); | 5504 __ add(ip, scratch, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5543 // -- ... | 5544 // -- ... |
| 5544 // -- r2 : api_function_address | 5545 // -- r2 : api_function_address |
| 5545 // ----------------------------------- | 5546 // ----------------------------------- |
| 5546 | 5547 |
| 5547 Register api_function_address = r2; | 5548 Register api_function_address = r2; |
| 5548 | 5549 |
| 5549 __ mov(r0, sp); // r0 = Handle<Name> | 5550 __ mov(r0, sp); // r0 = Handle<Name> |
| 5550 __ add(r1, r0, Operand(1 * kPointerSize)); // r1 = PCA | 5551 __ add(r1, r0, Operand(1 * kPointerSize)); // r1 = PCA |
| 5551 | 5552 |
| 5552 const int kApiStackSpace = 1; | 5553 const int kApiStackSpace = 1; |
| 5553 FrameScope frame_scope(masm, StackFrame::MANUAL); | 5554 FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL); |
| 5554 __ EnterExitFrame(false, kApiStackSpace); | 5555 __ EnterExitFrame(false, kApiStackSpace); |
| 5555 | 5556 |
| 5556 // Create PropertyAccessorInfo instance on the stack above the exit frame with | 5557 // Create PropertyAccessorInfo instance on the stack above the exit frame with |
| 5557 // r1 (internal::Object** args_) as the data. | 5558 // r1 (internal::Object** args_) as the data. |
| 5558 __ str(r1, MemOperand(sp, 1 * kPointerSize)); | 5559 __ str(r1, MemOperand(sp, 1 * kPointerSize)); |
| 5559 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& | 5560 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& |
| 5560 | 5561 |
| 5561 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | 5562 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
| 5562 | 5563 |
| 5563 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); | 5564 Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); |
| 5564 ExternalReference::Type thunk_type = | 5565 ExternalReference::Type thunk_type = |
| 5565 ExternalReference::PROFILING_GETTER_CALL; | 5566 ExternalReference::PROFILING_GETTER_CALL; |
| 5566 ApiFunction thunk_fun(thunk_address); | 5567 ApiFunction thunk_fun(thunk_address); |
| 5567 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, | 5568 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, |
| 5568 masm->isolate()); | 5569 masm->isolate()); |
| 5569 __ CallApiFunctionAndReturn(api_function_address, | 5570 __ CallApiFunctionAndReturn(api_function_address, |
| 5570 thunk_ref, | 5571 thunk_ref, |
| 5571 kStackUnwindSpace, | 5572 kStackUnwindSpace, |
| 5572 MemOperand(fp, 6 * kPointerSize), | 5573 MemOperand(fp, 6 * kPointerSize), |
| 5573 NULL); | 5574 NULL); |
| 5574 } | 5575 } |
| 5575 | 5576 |
| 5576 | 5577 |
| 5577 #undef __ | 5578 #undef __ |
| 5578 | 5579 |
| 5579 } } // namespace v8::internal | 5580 } } // namespace v8::internal |
| 5580 | 5581 |
| 5581 #endif // V8_TARGET_ARCH_ARM | 5582 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |