OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/arm/lithium-codegen-arm.h" | 7 #include "src/arm/lithium-codegen-arm.h" |
8 #include "src/arm/lithium-gap-resolver-arm.h" | 8 #include "src/arm/lithium-gap-resolver-arm.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/hydrogen-osr.h" | 10 #include "src/hydrogen-osr.h" |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 // end of the jump table. We also don't consider the pc load delta. | 318 // end of the jump table. We also don't consider the pc load delta. |
319 // Each entry in the jump table generates one instruction and inlines one | 319 // Each entry in the jump table generates one instruction and inlines one |
320 // 32bit data after it. | 320 // 32bit data after it. |
321 if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) + | 321 if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) + |
322 deopt_jump_table_.length() * 7)) { | 322 deopt_jump_table_.length() * 7)) { |
323 Abort(kGeneratedCodeIsTooLarge); | 323 Abort(kGeneratedCodeIsTooLarge); |
324 } | 324 } |
325 | 325 |
326 if (deopt_jump_table_.length() > 0) { | 326 if (deopt_jump_table_.length() > 0) { |
327 Comment(";;; -------------------- Jump table --------------------"); | 327 Comment(";;; -------------------- Jump table --------------------"); |
328 } | 328 Label table_start; |
329 Label table_start; | 329 __ bind(&table_start); |
330 __ bind(&table_start); | 330 Label needs_frame, call_l2; |
331 Label needs_frame; | 331 Address base = deopt_jump_table_[0].address; |
332 for (int i = 0; i < deopt_jump_table_.length(); i++) { | 332 for (int i = 0; i < deopt_jump_table_.length(); i++) { |
333 __ bind(&deopt_jump_table_[i].label); | 333 __ bind(&deopt_jump_table_[i].label); |
334 Address entry = deopt_jump_table_[i].address; | 334 Address entry = deopt_jump_table_[i].address; |
335 Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; | 335 Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; |
336 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); | 336 ASSERT(type == deopt_jump_table_[0].bailout_type); |
337 if (id == Deoptimizer::kNotDeoptimizationEntry) { | 337 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); |
338 Comment(";;; jump table entry %d.", i); | 338 ASSERT(id != Deoptimizer::kNotDeoptimizationEntry); |
339 } else { | |
340 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); | 339 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); |
340 // Second-level deopt table entries are contiguous and small, so instead | |
341 // of loading the full, absolute address of each one, load an immediate | |
342 // offset which will be added to the base address later. | |
343 __ mov(scratch0(), Operand(entry - base)); | |
344 if (deopt_jump_table_[i].needs_frame) { | |
345 ASSERT(!info()->saves_caller_doubles()); | |
346 if (needs_frame.is_bound()) { | |
347 __ b(&needs_frame); | |
348 } else { | |
349 __ bind(&needs_frame); | |
350 __ PushFixedFrame(); | |
351 // This variant of deopt can only be used with stubs. Since we don't | |
352 // have a function pointer to install in the stack frame that we're | |
353 // building, install a special marker there instead. | |
354 ASSERT(info()->IsStub()); | |
355 __ mov(ip, Operand(Smi::FromInt(StackFrame::STUB))); | |
356 __ push(ip); | |
357 __ add(fp, sp, | |
358 Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
359 // Add the base address to the offset previously loaded in scratch0. | |
360 __ add(scratch0(), scratch0(), | |
ulan
2014/06/23 11:41:40
Any reason you didn't move this out of the loop li
vincent.belliard
2014/06/23 11:52:29
Both versions generate the same number of instruct
vincent.belliard
2014/06/24 14:28:17
Done.
| |
361 Operand(ExternalReference::ForDeoptEntry(base))); | |
362 __ blx(scratch0()); | |
363 } | |
364 } else { | |
365 if (call_l2.is_bound()) { | |
366 __ b(&call_l2); | |
367 } else { | |
368 __ bind(&call_l2); | |
369 if (info()->saves_caller_doubles()) { | |
370 ASSERT(info()->IsStub()); | |
371 RestoreCallerDoubles(); | |
372 } | |
373 // Add the base address to the offset previously loaded in scratch0. | |
374 __ add(scratch0(), scratch0(), | |
375 Operand(ExternalReference::ForDeoptEntry(base))); | |
376 __ blx(scratch0()); | |
377 } | |
378 } | |
379 masm()->CheckConstPool(false, false); | |
341 } | 380 } |
342 if (deopt_jump_table_[i].needs_frame) { | |
343 ASSERT(!info()->saves_caller_doubles()); | |
344 __ mov(ip, Operand(ExternalReference::ForDeoptEntry(entry))); | |
345 if (needs_frame.is_bound()) { | |
346 __ b(&needs_frame); | |
347 } else { | |
348 __ bind(&needs_frame); | |
349 __ PushFixedFrame(); | |
350 // This variant of deopt can only be used with stubs. Since we don't | |
351 // have a function pointer to install in the stack frame that we're | |
352 // building, install a special marker there instead. | |
353 ASSERT(info()->IsStub()); | |
354 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); | |
355 __ push(scratch0()); | |
356 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
357 __ mov(lr, Operand(pc), LeaveCC, al); | |
358 __ mov(pc, ip); | |
359 } | |
360 } else { | |
361 if (info()->saves_caller_doubles()) { | |
362 ASSERT(info()->IsStub()); | |
363 RestoreCallerDoubles(); | |
364 } | |
365 __ mov(lr, Operand(pc), LeaveCC, al); | |
366 __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry))); | |
367 } | |
368 masm()->CheckConstPool(false, false); | |
369 } | 381 } |
370 | 382 |
371 // Force constant pool emission at the end of the deopt jump table to make | 383 // Force constant pool emission at the end of the deopt jump table to make |
372 // sure that no constant pools are emitted after. | 384 // sure that no constant pools are emitted after. |
373 masm()->CheckConstPool(true, false); | 385 masm()->CheckConstPool(true, false); |
374 | 386 |
375 // The deoptimization jump table is the last part of the instruction | 387 // The deoptimization jump table is the last part of the instruction |
376 // sequence. Mark the generated code as done unless we bailed out. | 388 // sequence. Mark the generated code as done unless we bailed out. |
377 if (!is_aborted()) status_ = DONE; | 389 if (!is_aborted()) status_ = DONE; |
378 return !is_aborted(); | 390 return !is_aborted(); |
(...skipping 5454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5833 __ Push(scope_info); | 5845 __ Push(scope_info); |
5834 __ push(ToRegister(instr->function())); | 5846 __ push(ToRegister(instr->function())); |
5835 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); | 5847 CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); |
5836 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5848 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5837 } | 5849 } |
5838 | 5850 |
5839 | 5851 |
5840 #undef __ | 5852 #undef __ |
5841 | 5853 |
5842 } } // namespace v8::internal | 5854 } } // namespace v8::internal |
OLD | NEW |