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 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1844 __ bind(&continuation); | 1844 __ bind(&continuation); |
1845 // When we arrive here, the stack top is the resume mode and | 1845 // When we arrive here, the stack top is the resume mode and |
1846 // result_register() holds the input value (the argument given to the | 1846 // result_register() holds the input value (the argument given to the |
1847 // respective resume operation). | 1847 // respective resume operation). |
1848 __ RecordGeneratorContinuation(); | 1848 __ RecordGeneratorContinuation(); |
1849 __ pop(ebx); | 1849 __ pop(ebx); |
1850 __ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::RETURN))); | 1850 __ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::RETURN))); |
1851 __ j(not_equal, &resume); | 1851 __ j(not_equal, &resume); |
1852 __ push(result_register()); | 1852 __ push(result_register()); |
1853 EmitCreateIteratorResult(true); | 1853 EmitCreateIteratorResult(true); |
1854 EmitUnwindBeforeReturn(); | 1854 EmitUnwindAndReturn(); |
1855 EmitReturnSequence(); | |
1856 | 1855 |
1857 __ bind(&suspend); | 1856 __ bind(&suspend); |
1858 VisitForAccumulatorValue(expr->generator_object()); | 1857 VisitForAccumulatorValue(expr->generator_object()); |
1859 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); | 1858 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
1860 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), | 1859 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), |
1861 Immediate(Smi::FromInt(continuation.pos()))); | 1860 Immediate(Smi::FromInt(continuation.pos()))); |
1862 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); | 1861 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); |
1863 __ mov(ecx, esi); | 1862 __ mov(ecx, esi); |
1864 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, | 1863 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, |
1865 kDontSaveFPRegs); | 1864 kDontSaveFPRegs); |
(...skipping 2601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4467 DCHECK(closure_scope->is_function_scope()); | 4466 DCHECK(closure_scope->is_function_scope()); |
4468 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 4467 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
4469 } | 4468 } |
4470 } | 4469 } |
4471 | 4470 |
4472 | 4471 |
4473 // ---------------------------------------------------------------------------- | 4472 // ---------------------------------------------------------------------------- |
4474 // Non-local control flow support. | 4473 // Non-local control flow support. |
4475 | 4474 |
4476 void FullCodeGenerator::EnterFinallyBlock() { | 4475 void FullCodeGenerator::EnterFinallyBlock() { |
4477 // Cook return address on top of stack (smi encoded Code* delta) | |
4478 DCHECK(!result_register().is(edx)); | |
4479 __ pop(edx); | |
4480 __ sub(edx, Immediate(masm_->CodeObject())); | |
4481 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); | |
4482 STATIC_ASSERT(kSmiTag == 0); | |
4483 __ SmiTag(edx); | |
4484 __ push(edx); | |
4485 | |
4486 // Store result register while executing finally block. | |
4487 __ push(result_register()); | |
4488 | |
4489 // Store pending message while executing finally block. | 4476 // Store pending message while executing finally block. |
4490 ExternalReference pending_message_obj = | 4477 ExternalReference pending_message_obj = |
4491 ExternalReference::address_of_pending_message_obj(isolate()); | 4478 ExternalReference::address_of_pending_message_obj(isolate()); |
4492 __ mov(edx, Operand::StaticVariable(pending_message_obj)); | 4479 __ mov(edx, Operand::StaticVariable(pending_message_obj)); |
4493 __ push(edx); | 4480 __ push(edx); |
4494 | 4481 |
4495 ClearPendingMessage(); | 4482 ClearPendingMessage(); |
4496 } | 4483 } |
4497 | 4484 |
4498 | 4485 |
4499 void FullCodeGenerator::ExitFinallyBlock() { | 4486 void FullCodeGenerator::ExitFinallyBlock() { |
4500 DCHECK(!result_register().is(edx)); | 4487 DCHECK(!result_register().is(edx)); |
4501 // Restore pending message from stack. | 4488 // Restore pending message from stack. |
4502 __ pop(edx); | 4489 __ pop(edx); |
4503 ExternalReference pending_message_obj = | 4490 ExternalReference pending_message_obj = |
4504 ExternalReference::address_of_pending_message_obj(isolate()); | 4491 ExternalReference::address_of_pending_message_obj(isolate()); |
4505 __ mov(Operand::StaticVariable(pending_message_obj), edx); | 4492 __ mov(Operand::StaticVariable(pending_message_obj), edx); |
4506 | |
4507 // Restore result register from stack. | |
4508 __ pop(result_register()); | |
4509 | |
4510 // Uncook return address. | |
4511 __ pop(edx); | |
4512 __ SmiUntag(edx); | |
4513 __ add(edx, Immediate(masm_->CodeObject())); | |
4514 __ jmp(edx); | |
4515 } | 4493 } |
4516 | 4494 |
4517 | 4495 |
4518 void FullCodeGenerator::ClearPendingMessage() { | 4496 void FullCodeGenerator::ClearPendingMessage() { |
4519 DCHECK(!result_register().is(edx)); | 4497 DCHECK(!result_register().is(edx)); |
4520 ExternalReference pending_message_obj = | 4498 ExternalReference pending_message_obj = |
4521 ExternalReference::address_of_pending_message_obj(isolate()); | 4499 ExternalReference::address_of_pending_message_obj(isolate()); |
4522 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 4500 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
4523 __ mov(Operand::StaticVariable(pending_message_obj), edx); | 4501 __ mov(Operand::StaticVariable(pending_message_obj), edx); |
4524 } | 4502 } |
4525 | 4503 |
4526 | 4504 |
4527 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { | 4505 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { |
4528 DCHECK(!slot.IsInvalid()); | 4506 DCHECK(!slot.IsInvalid()); |
4529 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), | 4507 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), |
4530 Immediate(SmiFromSlot(slot))); | 4508 Immediate(SmiFromSlot(slot))); |
4531 } | 4509 } |
4532 | 4510 |
| 4511 void FullCodeGenerator::DeferredCommands::EmitCommands() { |
| 4512 DCHECK(!result_register().is(edx)); |
| 4513 __ Pop(result_register()); // Restore the accumulator. |
| 4514 __ Pop(edx); // Get the token. |
| 4515 for (DeferredCommand cmd : commands_) { |
| 4516 Label skip; |
| 4517 __ cmp(edx, Immediate(Smi::FromInt(cmd.token))); |
| 4518 __ j(not_equal, &skip); |
| 4519 switch (cmd.command) { |
| 4520 case kReturn: |
| 4521 codegen_->EmitUnwindAndReturn(); |
| 4522 break; |
| 4523 case kThrow: |
| 4524 __ Push(result_register()); |
| 4525 __ CallRuntime(Runtime::kReThrow); |
| 4526 break; |
| 4527 case kContinue: |
| 4528 codegen_->EmitContinue(cmd.target); |
| 4529 break; |
| 4530 case kBreak: |
| 4531 codegen_->EmitBreak(cmd.target); |
| 4532 break; |
| 4533 } |
| 4534 __ bind(&skip); |
| 4535 } |
| 4536 } |
4533 | 4537 |
4534 #undef __ | 4538 #undef __ |
4535 | 4539 |
4536 | 4540 |
4537 static const byte kJnsInstruction = 0x79; | 4541 static const byte kJnsInstruction = 0x79; |
4538 static const byte kJnsOffset = 0x11; | 4542 static const byte kJnsOffset = 0x11; |
4539 static const byte kNopByteOne = 0x66; | 4543 static const byte kNopByteOne = 0x66; |
4540 static const byte kNopByteTwo = 0x90; | 4544 static const byte kNopByteTwo = 0x90; |
4541 #ifdef DEBUG | 4545 #ifdef DEBUG |
4542 static const byte kCallInstruction = 0xe8; | 4546 static const byte kCallInstruction = 0xe8; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4608 Assembler::target_address_at(call_target_address, | 4612 Assembler::target_address_at(call_target_address, |
4609 unoptimized_code)); | 4613 unoptimized_code)); |
4610 return OSR_AFTER_STACK_CHECK; | 4614 return OSR_AFTER_STACK_CHECK; |
4611 } | 4615 } |
4612 | 4616 |
4613 | 4617 |
4614 } // namespace internal | 4618 } // namespace internal |
4615 } // namespace v8 | 4619 } // namespace v8 |
4616 | 4620 |
4617 #endif // V8_TARGET_ARCH_X87 | 4621 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |