| 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 |