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 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 if (!instr->IsLazyBailout() && !instr->IsGap()) { | 370 if (!instr->IsLazyBailout() && !instr->IsGap()) { |
371 safepoints_.BumpLastLazySafepointIndex(); | 371 safepoints_.BumpLastLazySafepointIndex(); |
372 } | 372 } |
373 } | 373 } |
374 | 374 |
375 | 375 |
376 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { } | 376 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { } |
377 | 377 |
378 | 378 |
379 bool LCodeGen::GenerateJumpTable() { | 379 bool LCodeGen::GenerateJumpTable() { |
380 if (!jump_table_.length()) return !is_aborted(); | |
381 | |
380 Label needs_frame; | 382 Label needs_frame; |
381 if (jump_table_.length() > 0) { | 383 Comment(";;; -------------------- Jump table --------------------"); |
382 Comment(";;; -------------------- Jump table --------------------"); | 384 |
383 } | |
384 for (int i = 0; i < jump_table_.length(); i++) { | 385 for (int i = 0; i < jump_table_.length(); i++) { |
385 Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i]; | 386 Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i]; |
386 __ bind(&table_entry->label); | 387 __ bind(&table_entry->label); |
387 Address entry = table_entry->address; | 388 Address entry = table_entry->address; |
388 DeoptComment(table_entry->deopt_info); | 389 DeoptComment(table_entry->deopt_info); |
389 if (table_entry->needs_frame) { | 390 if (table_entry->needs_frame) { |
390 DCHECK(!info()->saves_caller_doubles()); | 391 DCHECK(!info()->saves_caller_doubles()); |
391 __ push(Immediate(ExternalReference::ForDeoptEntry(entry))); | 392 // Put deopt entry to the place where it will be used by ret(0) |
392 if (needs_frame.is_bound()) { | 393 __ mov(MemOperand(esp, -5 * kPointerSize), |
393 __ jmp(&needs_frame); | 394 Immediate(ExternalReference::ForDeoptEntry(entry))); |
Jarin
2015/03/17 12:44:22
This will not work because an asynchronous signal
| |
394 } else { | 395 // Save pc to the stack for 'from' argument of deoptimizer. |
395 __ bind(&needs_frame); | 396 __ call(&needs_frame); |
396 __ push(MemOperand(ebp, StandardFrameConstants::kContextOffset)); | |
397 // This variant of deopt can only be used with stubs. Since we don't | |
398 // have a function pointer to install in the stack frame that we're | |
399 // building, install a special marker there instead. | |
400 DCHECK(info()->IsStub()); | |
401 __ push(Immediate(Smi::FromInt(StackFrame::STUB))); | |
402 // Push a PC inside the function so that the deopt code can find where | |
403 // the deopt comes from. It doesn't have to be the precise return | |
404 // address of a "calling" LAZY deopt, it only has to be somewhere | |
405 // inside the code body. | |
406 Label push_approx_pc; | |
407 __ call(&push_approx_pc); | |
408 __ bind(&push_approx_pc); | |
409 // Push the continuation which was stashed were the ebp should | |
410 // be. Replace it with the saved ebp. | |
411 __ push(MemOperand(esp, 3 * kPointerSize)); | |
412 __ mov(MemOperand(esp, 4 * kPointerSize), ebp); | |
413 __ lea(ebp, MemOperand(esp, 4 * kPointerSize)); | |
414 __ ret(0); // Call the continuation without clobbering registers. | |
415 } | |
416 } else { | 397 } else { |
417 if (info()->saves_caller_doubles()) RestoreCallerDoubles(); | 398 if (info()->saves_caller_doubles()) RestoreCallerDoubles(); |
418 __ call(entry, RelocInfo::RUNTIME_ENTRY); | 399 __ call(entry, RelocInfo::RUNTIME_ENTRY); |
419 } | 400 } |
420 } | 401 } |
402 if (needs_frame.is_linked()) { | |
403 __ bind(&needs_frame); | |
404 __ push(MemOperand(ebp, StandardFrameConstants::kContextOffset)); | |
405 // This variant of deopt can only be used with stubs. Since we don't | |
406 // have a function pointer to install in the stack frame that we're | |
407 // building, install a special marker there instead. | |
408 DCHECK(info()->IsStub()); | |
409 __ push(Immediate(Smi::FromInt(StackFrame::STUB))); | |
410 // Copy the saved pc to the place where it would be used by Deoptimizer. | |
411 __ push(MemOperand(esp, 2 * kPointerSize)); | |
412 // Replace the original saved pc in the stack with ebp. | |
413 __ mov(MemOperand(esp, 3 * kPointerSize), ebp); | |
414 __ lea(ebp, MemOperand(esp, 3 * kPointerSize)); | |
415 // Move esp on top of entry address that has been saved earlier. | |
416 __ sub(esp, Immediate(kPointerSize)); | |
417 __ ret(0); // Call the continuation without clobbering registers. | |
418 } | |
421 return !is_aborted(); | 419 return !is_aborted(); |
422 } | 420 } |
423 | 421 |
424 | 422 |
425 bool LCodeGen::GenerateDeferredCode() { | 423 bool LCodeGen::GenerateDeferredCode() { |
426 DCHECK(is_generating()); | 424 DCHECK(is_generating()); |
427 if (deferred_.length() > 0) { | 425 if (deferred_.length() > 0) { |
428 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 426 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
429 LDeferredCode* code = deferred_[i]; | 427 LDeferredCode* code = deferred_[i]; |
430 | 428 |
(...skipping 5350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5781 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5779 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
5782 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5780 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5783 } | 5781 } |
5784 | 5782 |
5785 | 5783 |
5786 #undef __ | 5784 #undef __ |
5787 | 5785 |
5788 } } // namespace v8::internal | 5786 } } // namespace v8::internal |
5789 | 5787 |
5790 #endif // V8_TARGET_ARCH_IA32 | 5788 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |