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 3719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3730 | 3730 |
3731 __ mov(r2, Operand(ExternalReference::isolate_address())); | 3731 __ mov(r2, Operand(ExternalReference::isolate_address())); |
3732 | 3732 |
3733 // To let the GC traverse the return address of the exit frames, we need to | 3733 // To let the GC traverse the return address of the exit frames, we need to |
3734 // know where the return address is. The CEntryStub is unmovable, so | 3734 // know where the return address is. The CEntryStub is unmovable, so |
3735 // we can store the address on the stack to be able to find it again and | 3735 // we can store the address on the stack to be able to find it again and |
3736 // we never have to restore it, because it will not change. | 3736 // we never have to restore it, because it will not change. |
3737 // Compute the return address in lr to return to after the jump below. Pc is | 3737 // Compute the return address in lr to return to after the jump below. Pc is |
3738 // already at '+ 8' from the current instruction but return is after three | 3738 // already at '+ 8' from the current instruction but return is after three |
3739 // instructions so add another 4 to pc to get the return address. | 3739 // instructions so add another 4 to pc to get the return address. |
3740 masm->add(lr, pc, Operand(4)); | 3740 { |
3741 __ str(lr, MemOperand(sp, 0)); | 3741 // Prevent literal pool emission before return address. |
3742 masm->Jump(r5); | 3742 Assembler::BlockConstPoolScope block_const_pool(masm); |
| 3743 masm->add(lr, pc, Operand(4)); |
| 3744 __ str(lr, MemOperand(sp, 0)); |
| 3745 masm->Jump(r5); |
| 3746 } |
3743 | 3747 |
3744 if (always_allocate) { | 3748 if (always_allocate) { |
3745 // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1 | 3749 // It's okay to clobber r2 and r3 here. Don't mess with r0 and r1 |
3746 // though (contain the result). | 3750 // though (contain the result). |
3747 __ mov(r2, Operand(scope_depth)); | 3751 __ mov(r2, Operand(scope_depth)); |
3748 __ ldr(r3, MemOperand(r2)); | 3752 __ ldr(r3, MemOperand(r2)); |
3749 __ sub(r3, r3, Operand(1)); | 3753 __ sub(r3, r3, Operand(1)); |
3750 __ str(r3, MemOperand(r2)); | 3754 __ str(r3, MemOperand(r2)); |
3751 } | 3755 } |
3752 | 3756 |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3949 Label cont; | 3953 Label cont; |
3950 __ b(&cont); | 3954 __ b(&cont); |
3951 __ bind(&non_outermost_js); | 3955 __ bind(&non_outermost_js); |
3952 __ mov(ip, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); | 3956 __ mov(ip, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); |
3953 __ bind(&cont); | 3957 __ bind(&cont); |
3954 __ push(ip); | 3958 __ push(ip); |
3955 | 3959 |
3956 // Jump to a faked try block that does the invoke, with a faked catch | 3960 // Jump to a faked try block that does the invoke, with a faked catch |
3957 // block that sets the pending exception. | 3961 // block that sets the pending exception. |
3958 __ jmp(&invoke); | 3962 __ jmp(&invoke); |
3959 __ bind(&handler_entry); | 3963 |
3960 handler_offset_ = handler_entry.pos(); | 3964 // Block literal pool emission whilst taking the position of the handler |
3961 // Caught exception: Store result (exception) in the pending exception | 3965 // entry. This avoids making the assumption that literal pools are always |
3962 // field in the JSEnv and return a failure sentinel. Coming in here the | 3966 // emitted after an instruction is emitted, rather than before. |
3963 // fp will be invalid because the PushTryHandler below sets it to 0 to | 3967 { |
3964 // signal the existence of the JSEntry frame. | 3968 Assembler::BlockConstPoolScope block_const_pool(masm); |
3965 __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 3969 __ bind(&handler_entry); |
3966 isolate))); | 3970 handler_offset_ = handler_entry.pos(); |
| 3971 // Caught exception: Store result (exception) in the pending exception |
| 3972 // field in the JSEnv and return a failure sentinel. Coming in here the |
| 3973 // fp will be invalid because the PushTryHandler below sets it to 0 to |
| 3974 // signal the existence of the JSEntry frame. |
| 3975 __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
| 3976 isolate))); |
| 3977 } |
3967 __ str(r0, MemOperand(ip)); | 3978 __ str(r0, MemOperand(ip)); |
3968 __ mov(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); | 3979 __ mov(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); |
3969 __ b(&exit); | 3980 __ b(&exit); |
3970 | 3981 |
3971 // Invoke: Link this frame into the handler chain. There's only one | 3982 // Invoke: Link this frame into the handler chain. There's only one |
3972 // handler block in this code object, so its index is 0. | 3983 // handler block in this code object, so its index is 0. |
3973 __ bind(&invoke); | 3984 __ bind(&invoke); |
3974 // Must preserve r0-r4, r5-r7 are available. | 3985 // Must preserve r0-r4, r5-r7 are available. |
3975 __ PushTryHandler(StackHandler::JS_ENTRY, 0); | 3986 __ PushTryHandler(StackHandler::JS_ENTRY, 0); |
3976 // If an exception not caught by another handler occurs, this handler | 3987 // If an exception not caught by another handler occurs, this handler |
(...skipping 22 matching lines...) Expand all Loading... |
3999 isolate); | 4010 isolate); |
4000 __ mov(ip, Operand(construct_entry)); | 4011 __ mov(ip, Operand(construct_entry)); |
4001 } else { | 4012 } else { |
4002 ExternalReference entry(Builtins::kJSEntryTrampoline, isolate); | 4013 ExternalReference entry(Builtins::kJSEntryTrampoline, isolate); |
4003 __ mov(ip, Operand(entry)); | 4014 __ mov(ip, Operand(entry)); |
4004 } | 4015 } |
4005 __ ldr(ip, MemOperand(ip)); // deref address | 4016 __ ldr(ip, MemOperand(ip)); // deref address |
4006 | 4017 |
4007 // Branch and link to JSEntryTrampoline. We don't use the double underscore | 4018 // Branch and link to JSEntryTrampoline. We don't use the double underscore |
4008 // macro for the add instruction because we don't want the coverage tool | 4019 // macro for the add instruction because we don't want the coverage tool |
4009 // inserting instructions here after we read the pc. | 4020 // inserting instructions here after we read the pc. We block literal pool |
4010 __ mov(lr, Operand(pc)); | 4021 // emission for the same reason. |
4011 masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); | 4022 { |
| 4023 Assembler::BlockConstPoolScope block_const_pool(masm); |
| 4024 __ mov(lr, Operand(pc)); |
| 4025 masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 4026 } |
4012 | 4027 |
4013 // Unlink this frame from the handler chain. | 4028 // Unlink this frame from the handler chain. |
4014 __ PopTryHandler(); | 4029 __ PopTryHandler(); |
4015 | 4030 |
4016 __ bind(&exit); // r0 holds result | 4031 __ bind(&exit); // r0 holds result |
4017 // Check if the current stack frame is marked as the outermost JS frame. | 4032 // Check if the current stack frame is marked as the outermost JS frame. |
4018 Label non_outermost_js_2; | 4033 Label non_outermost_js_2; |
4019 __ pop(r5); | 4034 __ pop(r5); |
4020 __ cmp(r5, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 4035 __ cmp(r5, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
4021 __ b(ne, &non_outermost_js_2); | 4036 __ b(ne, &non_outermost_js_2); |
(...skipping 2783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6805 ExternalReference function) { | 6820 ExternalReference function) { |
6806 __ mov(r2, Operand(function)); | 6821 __ mov(r2, Operand(function)); |
6807 GenerateCall(masm, r2); | 6822 GenerateCall(masm, r2); |
6808 } | 6823 } |
6809 | 6824 |
6810 | 6825 |
6811 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, | 6826 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, |
6812 Register target) { | 6827 Register target) { |
6813 __ mov(lr, Operand(reinterpret_cast<intptr_t>(GetCode().location()), | 6828 __ mov(lr, Operand(reinterpret_cast<intptr_t>(GetCode().location()), |
6814 RelocInfo::CODE_TARGET)); | 6829 RelocInfo::CODE_TARGET)); |
| 6830 |
| 6831 // Prevent literal pool emission during calculation of return address. |
| 6832 Assembler::BlockConstPoolScope block_const_pool(masm); |
| 6833 |
6815 // Push return address (accessible to GC through exit frame pc). | 6834 // Push return address (accessible to GC through exit frame pc). |
6816 // Note that using pc with str is deprecated. | 6835 // Note that using pc with str is deprecated. |
6817 Label start; | 6836 Label start; |
6818 __ bind(&start); | 6837 __ bind(&start); |
6819 __ add(ip, pc, Operand(Assembler::kInstrSize)); | 6838 __ add(ip, pc, Operand(Assembler::kInstrSize)); |
6820 __ str(ip, MemOperand(sp, 0)); | 6839 __ str(ip, MemOperand(sp, 0)); |
6821 __ Jump(target); // Call the C++ function. | 6840 __ Jump(target); // Call the C++ function. |
6822 ASSERT_EQ(Assembler::kInstrSize + Assembler::kPcLoadDelta, | 6841 ASSERT_EQ(Assembler::kInstrSize + Assembler::kPcLoadDelta, |
6823 masm->SizeOfCodeGeneratedSince(&start)); | 6842 masm->SizeOfCodeGeneratedSince(&start)); |
6824 } | 6843 } |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7165 // written is in the address register. | 7184 // written is in the address register. |
7166 void RecordWriteStub::Generate(MacroAssembler* masm) { | 7185 void RecordWriteStub::Generate(MacroAssembler* masm) { |
7167 Label skip_to_incremental_noncompacting; | 7186 Label skip_to_incremental_noncompacting; |
7168 Label skip_to_incremental_compacting; | 7187 Label skip_to_incremental_compacting; |
7169 | 7188 |
7170 // The first two instructions are generated with labels so as to get the | 7189 // The first two instructions are generated with labels so as to get the |
7171 // offset fixed up correctly by the bind(Label*) call. We patch it back and | 7190 // offset fixed up correctly by the bind(Label*) call. We patch it back and |
7172 // forth between a compare instructions (a nop in this position) and the | 7191 // forth between a compare instructions (a nop in this position) and the |
7173 // real branch when we start and stop incremental heap marking. | 7192 // real branch when we start and stop incremental heap marking. |
7174 // See RecordWriteStub::Patch for details. | 7193 // See RecordWriteStub::Patch for details. |
7175 __ b(&skip_to_incremental_noncompacting); | 7194 { |
7176 __ b(&skip_to_incremental_compacting); | 7195 // Block literal pool emission, as the position of these two instructions |
| 7196 // is assumed by the patching code. |
| 7197 Assembler::BlockConstPoolScope block_const_pool(masm); |
| 7198 __ b(&skip_to_incremental_noncompacting); |
| 7199 __ b(&skip_to_incremental_compacting); |
| 7200 } |
7177 | 7201 |
7178 if (remembered_set_action_ == EMIT_REMEMBERED_SET) { | 7202 if (remembered_set_action_ == EMIT_REMEMBERED_SET) { |
7179 __ RememberedSetHelper(object_, | 7203 __ RememberedSetHelper(object_, |
7180 address_, | 7204 address_, |
7181 value_, | 7205 value_, |
7182 save_fp_regs_mode_, | 7206 save_fp_regs_mode_, |
7183 MacroAssembler::kReturnAtEnd); | 7207 MacroAssembler::kReturnAtEnd); |
7184 } | 7208 } |
7185 __ Ret(); | 7209 __ Ret(); |
7186 | 7210 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7405 __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r2, | 7429 __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r2, |
7406 &slow_elements); | 7430 &slow_elements); |
7407 __ Ret(); | 7431 __ Ret(); |
7408 } | 7432 } |
7409 | 7433 |
7410 #undef __ | 7434 #undef __ |
7411 | 7435 |
7412 } } // namespace v8::internal | 7436 } } // namespace v8::internal |
7413 | 7437 |
7414 #endif // V8_TARGET_ARCH_ARM | 7438 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |