OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
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 4337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4348 __ Push(result_register()); | 4348 __ Push(result_register()); |
4349 // Fall through. | 4349 // Fall through. |
4350 case Yield::kInitial: { | 4350 case Yield::kInitial: { |
4351 Label suspend, continuation, post_runtime, resume; | 4351 Label suspend, continuation, post_runtime, resume; |
4352 | 4352 |
4353 __ B(&suspend); | 4353 __ B(&suspend); |
4354 // TODO(jbramley): This label is bound here because the following code | 4354 // TODO(jbramley): This label is bound here because the following code |
4355 // looks at its pos(). Is it possible to do something more efficient here, | 4355 // looks at its pos(). Is it possible to do something more efficient here, |
4356 // perhaps using Adr? | 4356 // perhaps using Adr? |
4357 __ Bind(&continuation); | 4357 __ Bind(&continuation); |
| 4358 // When we arrive here, the stack top is the resume mode and |
| 4359 // result_register() holds the input value (the argument given to the |
| 4360 // respective resume operation). |
4358 __ RecordGeneratorContinuation(); | 4361 __ RecordGeneratorContinuation(); |
4359 __ B(&resume); | 4362 __ Pop(x1); |
| 4363 __ Cmp(x1, Smi::FromInt(JSGeneratorObject::RETURN)); |
| 4364 __ B(ne, &resume); |
| 4365 __ Push(result_register()); |
| 4366 EmitCreateIteratorResult(true); |
| 4367 EmitUnwindBeforeReturn(); |
| 4368 EmitReturnSequence(); |
4360 | 4369 |
4361 __ Bind(&suspend); | 4370 __ Bind(&suspend); |
4362 VisitForAccumulatorValue(expr->generator_object()); | 4371 VisitForAccumulatorValue(expr->generator_object()); |
4363 DCHECK((continuation.pos() > 0) && Smi::IsValid(continuation.pos())); | 4372 DCHECK((continuation.pos() > 0) && Smi::IsValid(continuation.pos())); |
4364 __ Mov(x1, Smi::FromInt(continuation.pos())); | 4373 __ Mov(x1, Smi::FromInt(continuation.pos())); |
4365 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); | 4374 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); |
4366 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); | 4375 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); |
4367 __ Mov(x1, cp); | 4376 __ Mov(x1, cp); |
4368 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, | 4377 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, |
4369 kLRHasBeenSaved, kDontSaveFPRegs); | 4378 kLRHasBeenSaved, kDontSaveFPRegs); |
4370 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); | 4379 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); |
4371 __ Cmp(__ StackPointer(), x1); | 4380 __ Cmp(__ StackPointer(), x1); |
4372 __ B(eq, &post_runtime); | 4381 __ B(eq, &post_runtime); |
4373 __ Push(x0); // generator object | 4382 __ Push(x0); // generator object |
4374 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 4383 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
4375 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4384 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4376 __ Bind(&post_runtime); | 4385 __ Bind(&post_runtime); |
4377 __ Pop(result_register()); | 4386 __ Pop(result_register()); |
4378 EmitReturnSequence(); | 4387 EmitReturnSequence(); |
4379 | 4388 |
4380 __ Bind(&resume); | 4389 __ Bind(&resume); |
4381 context()->Plug(result_register()); | 4390 context()->Plug(result_register()); |
4382 break; | 4391 break; |
4383 } | 4392 } |
4384 | 4393 |
4385 case Yield::kFinal: { | 4394 case Yield::kFinal: { |
4386 VisitForAccumulatorValue(expr->generator_object()); | 4395 VisitForAccumulatorValue(expr->generator_object()); |
4387 __ Mov(x1, Smi::FromInt(JSGeneratorObject::kGeneratorClosed)); | |
4388 __ Str(x1, FieldMemOperand(result_register(), | |
4389 JSGeneratorObject::kContinuationOffset)); | |
4390 // Pop value from top-of-stack slot, box result into result register. | 4396 // Pop value from top-of-stack slot, box result into result register. |
4391 EmitCreateIteratorResult(true); | 4397 EmitCreateIteratorResult(true); |
4392 EmitUnwindBeforeReturn(); | 4398 EmitUnwindBeforeReturn(); |
4393 EmitReturnSequence(); | 4399 EmitReturnSequence(); |
4394 break; | 4400 break; |
4395 } | 4401 } |
4396 | 4402 |
4397 case Yield::kDelegating: { | 4403 case Yield::kDelegating: { |
4398 VisitForStackValue(expr->generator_object()); | 4404 VisitForStackValue(expr->generator_object()); |
4399 | 4405 |
(...skipping 26 matching lines...) Expand all Loading... |
4426 EnterTryBlock(handler_index, &l_catch); | 4432 EnterTryBlock(handler_index, &l_catch); |
4427 const int try_block_size = TryCatch::kElementCount * kPointerSize; | 4433 const int try_block_size = TryCatch::kElementCount * kPointerSize; |
4428 __ Push(x0); // result | 4434 __ Push(x0); // result |
4429 | 4435 |
4430 __ B(&l_suspend); | 4436 __ B(&l_suspend); |
4431 // TODO(jbramley): This label is bound here because the following code | 4437 // TODO(jbramley): This label is bound here because the following code |
4432 // looks at its pos(). Is it possible to do something more efficient here, | 4438 // looks at its pos(). Is it possible to do something more efficient here, |
4433 // perhaps using Adr? | 4439 // perhaps using Adr? |
4434 __ Bind(&l_continuation); | 4440 __ Bind(&l_continuation); |
4435 __ RecordGeneratorContinuation(); | 4441 __ RecordGeneratorContinuation(); |
| 4442 __ pop(x1); |
| 4443 // TODO(neis): Ignoring the resume mode here is clearly wrong. Currently, |
| 4444 // return is not supported for yield*. The planned desugaring of yield* |
| 4445 // using do-expressions will naturally solve this. |
4436 __ B(&l_resume); | 4446 __ B(&l_resume); |
4437 | 4447 |
4438 __ Bind(&l_suspend); | 4448 __ Bind(&l_suspend); |
4439 const int generator_object_depth = kPointerSize + try_block_size; | 4449 const int generator_object_depth = kPointerSize + try_block_size; |
4440 __ Peek(x0, generator_object_depth); | 4450 __ Peek(x0, generator_object_depth); |
4441 __ Push(x0); // g | 4451 __ Push(x0); // g |
4442 __ Push(Smi::FromInt(handler_index)); // handler-index | 4452 __ Push(Smi::FromInt(handler_index)); // handler-index |
4443 DCHECK((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos())); | 4453 DCHECK((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos())); |
4444 __ Mov(x1, Smi::FromInt(l_continuation.pos())); | 4454 __ Mov(x1, Smi::FromInt(l_continuation.pos())); |
4445 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); | 4455 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4573 Label slow_resume; | 4583 Label slow_resume; |
4574 __ Cbnz(operand_stack_size, &slow_resume); | 4584 __ Cbnz(operand_stack_size, &slow_resume); |
4575 __ Ldr(x10, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | 4585 __ Ldr(x10, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
4576 __ Ldrsw(x11, | 4586 __ Ldrsw(x11, |
4577 UntagSmiFieldMemOperand(generator_object, | 4587 UntagSmiFieldMemOperand(generator_object, |
4578 JSGeneratorObject::kContinuationOffset)); | 4588 JSGeneratorObject::kContinuationOffset)); |
4579 __ Add(x10, x10, x11); | 4589 __ Add(x10, x10, x11); |
4580 __ Mov(x12, Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); | 4590 __ Mov(x12, Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); |
4581 __ Str(x12, FieldMemOperand(generator_object, | 4591 __ Str(x12, FieldMemOperand(generator_object, |
4582 JSGeneratorObject::kContinuationOffset)); | 4592 JSGeneratorObject::kContinuationOffset)); |
| 4593 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation. |
4583 __ Br(x10); | 4594 __ Br(x10); |
4584 | 4595 |
4585 __ Bind(&slow_resume); | 4596 __ Bind(&slow_resume); |
4586 } | 4597 } |
4587 | 4598 |
4588 // Otherwise, we push holes for the operand stack and call the runtime to fix | 4599 // Otherwise, we push holes for the operand stack and call the runtime to fix |
4589 // up the stack and the handlers. | 4600 // up the stack and the handlers. |
4590 __ PushMultipleTimes(the_hole, operand_stack_size); | 4601 __ PushMultipleTimes(the_hole, operand_stack_size); |
4591 | 4602 |
4592 __ Mov(x10, Smi::FromInt(resume_mode)); | 4603 __ Mov(x10, Smi::FromInt(resume_mode)); |
| 4604 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation. |
4593 __ Push(generator_object, result_register(), x10); | 4605 __ Push(generator_object, result_register(), x10); |
4594 __ CallRuntime(Runtime::kResumeJSGeneratorObject); | 4606 __ CallRuntime(Runtime::kResumeJSGeneratorObject); |
4595 // Not reached: the runtime call returns elsewhere. | 4607 // Not reached: the runtime call returns elsewhere. |
4596 __ Unreachable(); | 4608 __ Unreachable(); |
4597 | 4609 |
4598 __ Bind(&done); | 4610 __ Bind(&done); |
4599 context()->Plug(result_register()); | 4611 context()->Plug(result_register()); |
4600 } | 4612 } |
4601 | 4613 |
4602 | 4614 |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4835 } | 4847 } |
4836 | 4848 |
4837 return INTERRUPT; | 4849 return INTERRUPT; |
4838 } | 4850 } |
4839 | 4851 |
4840 | 4852 |
4841 } // namespace internal | 4853 } // namespace internal |
4842 } // namespace v8 | 4854 } // namespace v8 |
4843 | 4855 |
4844 #endif // V8_TARGET_ARCH_ARM64 | 4856 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |