OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 __ b(&return_label_); | 187 __ b(&return_label_); |
188 } else { | 188 } else { |
189 __ bind(&return_label_); | 189 __ bind(&return_label_); |
190 if (FLAG_trace) { | 190 if (FLAG_trace) { |
191 // Push the return value on the stack as the parameter. | 191 // Push the return value on the stack as the parameter. |
192 // Runtime::TraceExit returns its parameter in r0. | 192 // Runtime::TraceExit returns its parameter in r0. |
193 __ push(r0); | 193 __ push(r0); |
194 __ CallRuntime(Runtime::kTraceExit, 1); | 194 __ CallRuntime(Runtime::kTraceExit, 1); |
195 } | 195 } |
196 | 196 |
| 197 #ifdef DEBUG |
197 // Add a label for checking the size of the code used for returning. | 198 // Add a label for checking the size of the code used for returning. |
198 Label check_exit_codesize; | 199 Label check_exit_codesize; |
199 masm_->bind(&check_exit_codesize); | 200 masm_->bind(&check_exit_codesize); |
| 201 #endif |
200 | 202 |
201 // Calculate the exact length of the return sequence and make sure that | 203 { |
202 // the constant pool is not emitted inside of the return sequence. | 204 // Make sure that the constant pool is not emitted inside of the return |
203 int num_parameters = scope()->num_parameters(); | 205 // sequence. |
204 int32_t sp_delta = (num_parameters + 1) * kPointerSize; | 206 Assembler::BlockConstPoolScope block_const_pool(masm_); |
205 int return_sequence_length = Assembler::kJSReturnSequenceLength; | 207 |
206 if (!masm_->ImmediateFitsAddrMode1Instruction(sp_delta)) { | 208 // Here we use masm_-> instead of the __ macro to avoid the code coverage |
207 // Additional mov instruction generated. | 209 // tool from instrumenting as we rely on the code size here. |
208 return_sequence_length++; | 210 int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize; |
| 211 CodeGenerator::RecordPositions(masm_, position); |
| 212 __ RecordJSReturn(); |
| 213 masm_->mov(sp, fp); |
| 214 masm_->ldm(ia_w, sp, fp.bit() | lr.bit()); |
| 215 masm_->add(sp, sp, Operand(sp_delta)); |
| 216 masm_->Jump(lr); |
209 } | 217 } |
210 masm_->BlockConstPoolFor(return_sequence_length); | |
211 | 218 |
212 CodeGenerator::RecordPositions(masm_, position); | 219 #ifdef DEBUG |
213 __ RecordJSReturn(); | |
214 __ mov(sp, fp); | |
215 __ ldm(ia_w, sp, fp.bit() | lr.bit()); | |
216 __ add(sp, sp, Operand(sp_delta)); | |
217 __ Jump(lr); | |
218 | |
219 // Check that the size of the code used for returning matches what is | 220 // Check that the size of the code used for returning matches what is |
220 // expected by the debugger. The add instruction above is an addressing | 221 // expected by the debugger. If the sp_delts above cannot be encoded in the |
221 // mode 1 instruction where there are restrictions on which immediate values | 222 // add instruction the add will generate two instructions. |
222 // can be encoded in the instruction and which immediate values requires | 223 int return_sequence_length = |
223 // use of an additional instruction for moving the immediate to a temporary | 224 masm_->InstructionsGeneratedSince(&check_exit_codesize); |
224 // register. | 225 CHECK(return_sequence_length == Assembler::kJSReturnSequenceLength || |
225 ASSERT_EQ(return_sequence_length, | 226 return_sequence_length == Assembler::kJSReturnSequenceLength + 1); |
226 masm_->InstructionsGeneratedSince(&check_exit_codesize)); | 227 #endif |
227 } | 228 } |
228 } | 229 } |
229 | 230 |
230 | 231 |
231 void FullCodeGenerator::Apply(Expression::Context context, Register reg) { | 232 void FullCodeGenerator::Apply(Expression::Context context, Register reg) { |
232 switch (context) { | 233 switch (context) { |
233 case Expression::kUninitialized: | 234 case Expression::kUninitialized: |
234 UNREACHABLE(); | 235 UNREACHABLE(); |
235 | 236 |
236 case Expression::kEffect: | 237 case Expression::kEffect: |
(...skipping 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1858 __ pop(result_register()); | 1859 __ pop(result_register()); |
1859 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 1860 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); |
1860 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 1861 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
1861 __ add(pc, r1, Operand(masm_->CodeObject())); | 1862 __ add(pc, r1, Operand(masm_->CodeObject())); |
1862 } | 1863 } |
1863 | 1864 |
1864 | 1865 |
1865 #undef __ | 1866 #undef __ |
1866 | 1867 |
1867 } } // namespace v8::internal | 1868 } } // namespace v8::internal |
OLD | NEW |