Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: src/a64/full-codegen-a64.cc

Issue 142813003: A64: Synchronize with r15358. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/a64/frames-a64.cc ('k') | src/a64/ic-a64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1669 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 __ Push(x0); // Save result on stack 1680 __ Push(x0); // Save result on stack
1681 result_saved = true; 1681 result_saved = true;
1682 } 1682 }
1683 switch (property->kind()) { 1683 switch (property->kind()) {
1684 case ObjectLiteral::Property::CONSTANT: 1684 case ObjectLiteral::Property::CONSTANT:
1685 UNREACHABLE(); 1685 UNREACHABLE();
1686 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1686 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1687 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1687 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
1688 // Fall through. 1688 // Fall through.
1689 case ObjectLiteral::Property::COMPUTED: 1689 case ObjectLiteral::Property::COMPUTED:
1690 if (key->handle()->IsInternalizedString()) { 1690 if (key->value()->IsInternalizedString()) {
1691 if (property->emit_store()) { 1691 if (property->emit_store()) {
1692 VisitForAccumulatorValue(value); 1692 VisitForAccumulatorValue(value);
1693 __ Mov(x2, Operand(key->handle())); 1693 __ Mov(x2, Operand(key->value()));
1694 __ Peek(x1, 0); 1694 __ Peek(x1, 0);
1695 Handle<Code> ic = is_classic_mode() 1695 Handle<Code> ic = is_classic_mode()
1696 ? isolate()->builtins()->StoreIC_Initialize() 1696 ? isolate()->builtins()->StoreIC_Initialize()
1697 : isolate()->builtins()->StoreIC_Initialize_Strict(); 1697 : isolate()->builtins()->StoreIC_Initialize_Strict();
1698 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); 1698 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId());
1699 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1699 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1700 } else { 1700 } else {
1701 VisitForEffect(value); 1701 VisitForEffect(value);
1702 } 1702 }
1703 break; 1703 break;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1819 } 1819 }
1820 1820
1821 bool result_saved = false; // Is the result saved to the stack? 1821 bool result_saved = false; // Is the result saved to the stack?
1822 1822
1823 // Emit code to evaluate all the non-constant subexpressions and to store 1823 // Emit code to evaluate all the non-constant subexpressions and to store
1824 // them into the newly cloned array. 1824 // them into the newly cloned array.
1825 for (int i = 0; i < length; i++) { 1825 for (int i = 0; i < length; i++) {
1826 Expression* subexpr = subexprs->at(i); 1826 Expression* subexpr = subexprs->at(i);
1827 // If the subexpression is a literal or a simple materialized literal it 1827 // If the subexpression is a literal or a simple materialized literal it
1828 // is already set in the cloned array. 1828 // is already set in the cloned array.
1829 if (subexpr->AsLiteral() != NULL || 1829 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1830 CompileTimeValue::IsCompileTimeValue(subexpr)) {
1831 continue;
1832 }
1833 1830
1834 if (!result_saved) { 1831 if (!result_saved) {
1835 __ Push(x0); 1832 __ Push(x0);
1836 __ Push(Smi::FromInt(expr->literal_index())); 1833 __ Push(Smi::FromInt(expr->literal_index()));
1837 result_saved = true; 1834 result_saved = true;
1838 } 1835 }
1839 VisitForAccumulatorValue(subexpr); 1836 VisitForAccumulatorValue(subexpr);
1840 1837
1841 if (IsFastObjectElementsKind(constant_elements_kind)) { 1838 if (IsFastObjectElementsKind(constant_elements_kind)) {
1842 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1839 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1974 case KEYED_PROPERTY: 1971 case KEYED_PROPERTY:
1975 EmitKeyedPropertyAssignment(expr); 1972 EmitKeyedPropertyAssignment(expr);
1976 break; 1973 break;
1977 } 1974 }
1978 } 1975 }
1979 1976
1980 1977
1981 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1978 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1982 SetSourcePosition(prop->position()); 1979 SetSourcePosition(prop->position());
1983 Literal* key = prop->key()->AsLiteral(); 1980 Literal* key = prop->key()->AsLiteral();
1984 __ Mov(x2, Operand(key->handle())); 1981 __ Mov(x2, Operand(key->value()));
1985 // Call load IC. It has arguments receiver and property name x0 and x2. 1982 // Call load IC. It has arguments receiver and property name x0 and x2.
1986 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1983 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1987 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); 1984 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
1988 } 1985 }
1989 1986
1990 1987
1991 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1988 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1992 SetSourcePosition(prop->position()); 1989 SetSourcePosition(prop->position());
1993 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 1990 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1994 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1991 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
2138 EmitVariableAssignment(var, Token::ASSIGN); 2135 EmitVariableAssignment(var, Token::ASSIGN);
2139 break; 2136 break;
2140 } 2137 }
2141 case NAMED_PROPERTY: { 2138 case NAMED_PROPERTY: {
2142 __ Push(x0); // Preserve value. 2139 __ Push(x0); // Preserve value.
2143 VisitForAccumulatorValue(prop->obj()); 2140 VisitForAccumulatorValue(prop->obj());
2144 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid 2141 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid
2145 // this copy. 2142 // this copy.
2146 __ Mov(x1, x0); 2143 __ Mov(x1, x0);
2147 __ Pop(x0); // Restore value. 2144 __ Pop(x0); // Restore value.
2148 __ Mov(x2, Operand(prop->key()->AsLiteral()->handle())); 2145 __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
2149 Handle<Code> ic = is_classic_mode() 2146 Handle<Code> ic = is_classic_mode()
2150 ? isolate()->builtins()->StoreIC_Initialize() 2147 ? isolate()->builtins()->StoreIC_Initialize()
2151 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2148 : isolate()->builtins()->StoreIC_Initialize_Strict();
2152 CallIC(ic); 2149 CallIC(ic);
2153 break; 2150 break;
2154 } 2151 }
2155 case KEYED_PROPERTY: { 2152 case KEYED_PROPERTY: {
2156 __ Push(x0); // Preserve value. 2153 __ Push(x0); // Preserve value.
2157 VisitForStackValue(prop->obj()); 2154 VisitForStackValue(prop->obj());
2158 VisitForAccumulatorValue(prop->key()); 2155 VisitForAccumulatorValue(prop->key());
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2268 2265
2269 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2266 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2270 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); 2267 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment");
2271 // Assignment to a property, using a named store IC. 2268 // Assignment to a property, using a named store IC.
2272 Property* prop = expr->target()->AsProperty(); 2269 Property* prop = expr->target()->AsProperty();
2273 ASSERT(prop != NULL); 2270 ASSERT(prop != NULL);
2274 ASSERT(prop->key()->AsLiteral() != NULL); 2271 ASSERT(prop->key()->AsLiteral() != NULL);
2275 2272
2276 // Record source code position before IC call. 2273 // Record source code position before IC call.
2277 SetSourcePosition(expr->position()); 2274 SetSourcePosition(expr->position());
2278 __ Mov(x2, Operand(prop->key()->AsLiteral()->handle())); 2275 __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
2279 __ Pop(x1); 2276 __ Pop(x1);
2280 2277
2281 Handle<Code> ic = is_classic_mode() 2278 Handle<Code> ic = is_classic_mode()
2282 ? isolate()->builtins()->StoreIC_Initialize() 2279 ? isolate()->builtins()->StoreIC_Initialize()
2283 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2280 : isolate()->builtins()->StoreIC_Initialize_Strict();
2284 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); 2281 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
2285 2282
2286 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2283 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2287 context()->Plug(x0); 2284 context()->Plug(x0);
2288 } 2285 }
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
2555 // The receiver is either the global receiver or an object found 2552 // The receiver is either the global receiver or an object found
2556 // by LoadContextSlot. That object could be the hole if the 2553 // by LoadContextSlot. That object could be the hole if the
2557 // receiver is implicitly the global object. 2554 // receiver is implicitly the global object.
2558 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); 2555 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT);
2559 } else if (property != NULL) { 2556 } else if (property != NULL) {
2560 { PreservePositionScope scope(masm()->positions_recorder()); 2557 { PreservePositionScope scope(masm()->positions_recorder());
2561 VisitForStackValue(property->obj()); 2558 VisitForStackValue(property->obj());
2562 } 2559 }
2563 if (property->key()->IsPropertyName()) { 2560 if (property->key()->IsPropertyName()) {
2564 EmitCallWithIC(expr, 2561 EmitCallWithIC(expr,
2565 property->key()->AsLiteral()->handle(), 2562 property->key()->AsLiteral()->value(),
2566 RelocInfo::CODE_TARGET); 2563 RelocInfo::CODE_TARGET);
2567 } else { 2564 } else {
2568 EmitKeyedCallWithIC(expr, property->key()); 2565 EmitKeyedCallWithIC(expr, property->key());
2569 } 2566 }
2570 2567
2571 } else { 2568 } else {
2572 // Call to an arbitrary expression not handled specially above. 2569 // Call to an arbitrary expression not handled specially above.
2573 { PreservePositionScope scope(masm()->positions_recorder()); 2570 { PreservePositionScope scope(masm()->positions_recorder());
2574 VisitForStackValue(callee); 2571 VisitForStackValue(callee);
2575 } 2572 }
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
3167 3164
3168 __ Bind(&done); 3165 __ Bind(&done);
3169 context()->Plug(x0); 3166 context()->Plug(x0);
3170 } 3167 }
3171 3168
3172 3169
3173 void FullCodeGenerator::EmitDateField(CallRuntime* expr) { 3170 void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
3174 ZoneList<Expression*>* args = expr->arguments(); 3171 ZoneList<Expression*>* args = expr->arguments();
3175 ASSERT(args->length() == 2); 3172 ASSERT(args->length() == 2);
3176 ASSERT_NE(NULL, args->at(1)->AsLiteral()); 3173 ASSERT_NE(NULL, args->at(1)->AsLiteral());
3177 Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->handle())); 3174 Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
3178 3175
3179 VisitForAccumulatorValue(args->at(0)); // Load the object. 3176 VisitForAccumulatorValue(args->at(0)); // Load the object.
3180 3177
3181 Label runtime, done, not_date_object; 3178 Label runtime, done, not_date_object;
3182 Register object = x0; 3179 Register object = x0;
3183 Register result = x0; 3180 Register result = x0;
3184 Register stamp_addr = x10; 3181 Register stamp_addr = x10;
3185 Register stamp_cache = x11; 3182 Register stamp_cache = x11;
3186 3183
3187 __ JumpIfSmi(object, &not_date_object); 3184 __ JumpIfSmi(object, &not_date_object);
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
3590 VisitForStackValue(args->at(2)); 3587 VisitForStackValue(args->at(2));
3591 __ CallStub(&stub); 3588 __ CallStub(&stub);
3592 context()->Plug(x0); 3589 context()->Plug(x0);
3593 } 3590 }
3594 3591
3595 3592
3596 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { 3593 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
3597 ZoneList<Expression*>* args = expr->arguments(); 3594 ZoneList<Expression*>* args = expr->arguments();
3598 ASSERT_EQ(2, args->length()); 3595 ASSERT_EQ(2, args->length());
3599 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3596 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3600 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 3597 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value();
3601 3598
3602 Handle<FixedArray> jsfunction_result_caches( 3599 Handle<FixedArray> jsfunction_result_caches(
3603 isolate()->native_context()->jsfunction_result_caches()); 3600 isolate()->native_context()->jsfunction_result_caches());
3604 if (jsfunction_result_caches->length() <= cache_id) { 3601 if (jsfunction_result_caches->length() <= cache_id) {
3605 __ Abort("Attempt to use undefined cache."); 3602 __ Abort("Attempt to use undefined cache.");
3606 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 3603 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
3607 context()->Plug(x0); 3604 context()->Plug(x0);
3608 return; 3605 return;
3609 } 3606 }
3610 3607
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
4250 context()->PlugTOS(); 4247 context()->PlugTOS();
4251 } 4248 }
4252 } else { 4249 } else {
4253 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4250 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4254 Token::ASSIGN); 4251 Token::ASSIGN);
4255 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4252 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4256 context()->Plug(x0); 4253 context()->Plug(x0);
4257 } 4254 }
4258 break; 4255 break;
4259 case NAMED_PROPERTY: { 4256 case NAMED_PROPERTY: {
4260 __ Mov(x2, Operand(prop->key()->AsLiteral()->handle())); 4257 __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
4261 __ Pop(x1); 4258 __ Pop(x1);
4262 Handle<Code> ic = is_classic_mode() 4259 Handle<Code> ic = is_classic_mode()
4263 ? isolate()->builtins()->StoreIC_Initialize() 4260 ? isolate()->builtins()->StoreIC_Initialize()
4264 : isolate()->builtins()->StoreIC_Initialize_Strict(); 4261 : isolate()->builtins()->StoreIC_Initialize_Strict();
4265 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); 4262 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
4266 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4263 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4267 if (expr->is_postfix()) { 4264 if (expr->is_postfix()) {
4268 if (!context()->IsEffect()) { 4265 if (!context()->IsEffect()) {
4269 context()->PlugTOS(); 4266 context()->PlugTOS();
4270 } 4267 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
4525 context()->Plug(x0); 4522 context()->Plug(x0);
4526 } 4523 }
4527 4524
4528 4525
4529 void FullCodeGenerator::VisitYield(Yield* expr) { 4526 void FullCodeGenerator::VisitYield(Yield* expr) {
4530 Comment cmnt(masm_, "[ Yield"); 4527 Comment cmnt(masm_, "[ Yield");
4531 // Evaluate yielded value first; the initial iterator definition depends on 4528 // Evaluate yielded value first; the initial iterator definition depends on
4532 // this. It stays on the stack while we update the iterator. 4529 // this. It stays on the stack while we update the iterator.
4533 VisitForStackValue(expr->expression()); 4530 VisitForStackValue(expr->expression());
4534 4531
4532 // TODO(jbramley): Tidy this up once the merge is done, using named registers
4533 // and suchlike. The implementation changes a little by bleeding_edge so I
4534 // don't want to spend too much time on it now.
4535
4535 switch (expr->yield_kind()) { 4536 switch (expr->yield_kind()) {
4536 case Yield::SUSPEND: 4537 case Yield::SUSPEND:
4537 // Pop value from top-of-stack slot; box result into result register. 4538 // Pop value from top-of-stack slot; box result into result register.
4538 EmitCreateIteratorResult(false); 4539 EmitCreateIteratorResult(false);
4539 __ Push(result_register()); 4540 __ Push(result_register());
4540 // Fall through. 4541 // Fall through.
4541 case Yield::INITIAL: { 4542 case Yield::INITIAL: {
4542 VisitForStackValue(expr->generator_object()); 4543 Label suspend, continuation, post_runtime, resume;
4544
4545 __ B(&suspend);
4546
4547 // TODO(jbramley): This label is bound here because the following code
4548 // looks at its pos(). Is it possible to do something more efficient here,
4549 // perhaps using Adr?
4550 __ Bind(&continuation);
4551 __ B(&resume);
4552
4553 __ Bind(&suspend);
4554 VisitForAccumulatorValue(expr->generator_object());
4555 ASSERT((continuation.pos() > 0) && Smi::IsValid(continuation.pos()));
4556 __ Mov(x1, Operand(Smi::FromInt(continuation.pos())));
4557 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
4558 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset));
4559 __ Mov(x1, cp);
4560 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2,
4561 kLRHasBeenSaved, kDontSaveFPRegs);
4562 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset);
4563 __ Cmp(__ StackPointer(), x1);
4564 __ B(eq, &post_runtime);
4565 __ Push(x0); // generator object
4543 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 4566 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
4544 __ Ldr(context_register(), 4567 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4545 MemOperand(fp, StandardFrameConstants::kContextOffset)); 4568 __ Bind(&post_runtime);
4546
4547 Label resume;
4548 __ JumpIfNotRoot(result_register(), Heap::kTheHoleValueRootIndex,
4549 &resume);
4550 __ Pop(result_register()); 4569 __ Pop(result_register());
4551 EmitReturnSequence(); 4570 EmitReturnSequence();
4552 4571
4553 __ Bind(&resume); 4572 __ Bind(&resume);
4554 context()->Plug(result_register()); 4573 context()->Plug(result_register());
4555 break; 4574 break;
4556 } 4575 }
4557 4576
4558 case Yield::FINAL: { 4577 case Yield::FINAL: {
4559 VisitForAccumulatorValue(expr->generator_object()); 4578 VisitForAccumulatorValue(expr->generator_object());
4560 __ Mov(x1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); 4579 __ Mov(x1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
4561 __ Str(x1, FieldMemOperand(result_register(), 4580 __ Str(x1, FieldMemOperand(result_register(),
4562 JSGeneratorObject::kContinuationOffset)); 4581 JSGeneratorObject::kContinuationOffset));
4563 // Pop value from top-of-stack slot, box result into result register. 4582 // Pop value from top-of-stack slot, box result into result register.
4564 EmitCreateIteratorResult(true); 4583 EmitCreateIteratorResult(true);
4565 EmitUnwindBeforeReturn(); 4584 EmitUnwindBeforeReturn();
4566 EmitReturnSequence(); 4585 EmitReturnSequence();
4567 break; 4586 break;
4568 } 4587 }
4569 4588
4570 case Yield::DELEGATING: { 4589 case Yield::DELEGATING: {
4571 VisitForStackValue(expr->generator_object()); 4590 VisitForStackValue(expr->generator_object());
4572 4591
4573 // Initial stack layout is as follows: 4592 // Initial stack layout is as follows:
4574 // [sp + 1 * kPointerSize] iter 4593 // [sp + 1 * kPointerSize] iter
4575 // [sp + 0 * kPointerSize] g 4594 // [sp + 0 * kPointerSize] g
4576 4595
4577 // TODO(jbramley): Tidy this up once the merge is done, using named 4596 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
4578 // registers and suchlike. The implementation changes a little by 4597 Label l_next, l_call, l_loop;
4579 // bleeding_edge so I don't want to spend too much time on it now.
4580
4581 Label l_catch, l_try, l_resume, l_next, l_call, l_loop;
4582 // Initial send value is undefined. 4598 // Initial send value is undefined.
4583 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 4599 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
4584 __ B(&l_next); 4600 __ B(&l_next);
4585 4601
4586 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 4602 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
4587 __ Bind(&l_catch); 4603 __ Bind(&l_catch);
4588 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 4604 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
4589 __ LoadRoot(x2, Heap::kthrow_stringRootIndex); // "throw" 4605 __ LoadRoot(x2, Heap::kthrow_stringRootIndex); // "throw"
4590 __ Peek(x3, 1 * kPointerSize); // iter 4606 __ Peek(x3, 1 * kPointerSize); // iter
4591 __ Push(x3); // iter 4607 __ Push(x3); // iter
4592 __ Push(x0); // exception 4608 __ Push(x0); // exception
4593 __ B(&l_call); 4609 __ B(&l_call);
4594 4610
4595 // try { received = %yield result } 4611 // try { received = %yield result }
4596 // Shuffle the received result above a try handler and yield it without 4612 // Shuffle the received result above a try handler and yield it without
4597 // re-boxing. 4613 // re-boxing.
4598 __ Bind(&l_try); 4614 __ Bind(&l_try);
4599 __ Pop(x0); // result 4615 __ Pop(x0); // result
4600 __ PushTryHandler(StackHandler::CATCH, expr->index()); 4616 __ PushTryHandler(StackHandler::CATCH, expr->index());
4601 const int handler_size = StackHandlerConstants::kSize; 4617 const int handler_size = StackHandlerConstants::kSize;
4602 __ Push(x0); // result 4618 __ Push(x0); // result
4603 __ Peek(x3, (1 * kPointerSize) + handler_size); // g 4619 __ B(&l_suspend);
4604 __ Push(x3); // g 4620
4621 // TODO(jbramley): This label is bound here because the following code
4622 // looks at its pos(). Is it possible to do something more efficient here,
4623 // perhaps using Adr?
4624 __ Bind(&l_continuation);
4625 __ B(&l_resume);
4626
4627 __ Bind(&l_suspend);
4628 const int generator_object_depth = kPointerSize + handler_size;
4629 __ Peek(x0, generator_object_depth);
4630 __ Push(x0); // g
4631 ASSERT((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos()));
4632 __ Mov(x1, Operand(Smi::FromInt(l_continuation.pos())));
4633 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset));
4634 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset));
4635 __ Mov(x1, cp);
4636 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2,
4637 kLRHasBeenSaved, kDontSaveFPRegs);
4605 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 4638 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
4606 __ Ldr(context_register(), 4639 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4607 MemOperand(fp, StandardFrameConstants::kContextOffset));
4608 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &l_resume);
4609 __ Pop(x0); // result 4640 __ Pop(x0); // result
4610 EmitReturnSequence(); 4641 EmitReturnSequence();
4611 __ Bind(&l_resume); // received in x0 4642 __ Bind(&l_resume); // received in x0
4612 __ PopTryHandler(); 4643 __ PopTryHandler();
4613 4644
4614 // receiver = iter; f = 'next'; arg = received; 4645 // receiver = iter; f = 'next'; arg = received;
4615 __ Bind(&l_next); 4646 __ Bind(&l_next);
4616 __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next" 4647 __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next"
4617 __ Peek(x3, 1 * kPointerSize); // iter 4648 __ Peek(x3, 1 * kPointerSize); // iter
4618 __ Push(x3); // iter 4649 __ Push(x3); // iter
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
4688 // The number of arguments is stored as an int32_t, and -1 is a marker 4719 // The number of arguments is stored as an int32_t, and -1 is a marker
4689 // (SharedFunctionInfo::kDontAdaptArgumentsSentinel), so we need sign 4720 // (SharedFunctionInfo::kDontAdaptArgumentsSentinel), so we need sign
4690 // extension to correctly handle it. However, in this case, we operate on 4721 // extension to correctly handle it. However, in this case, we operate on
4691 // 32-bit W registers, so extension isn't required. 4722 // 32-bit W registers, so extension isn't required.
4692 __ Ldr(w10, FieldMemOperand(x10, 4723 __ Ldr(w10, FieldMemOperand(x10,
4693 SharedFunctionInfo::kFormalParameterCountOffset)); 4724 SharedFunctionInfo::kFormalParameterCountOffset));
4694 __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex); 4725 __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex);
4695 4726
4696 // TODO(jbramley): Write a variant of PushMultipleTimes which takes a register 4727 // TODO(jbramley): Write a variant of PushMultipleTimes which takes a register
4697 // instead of a constant count, and use it to replace this loop. 4728 // instead of a constant count, and use it to replace this loop.
4698 // TODO(jbramley): ARM doesn't seem to untag its smis here, so it pushes twice
4699 // as many holes as it needs to.
4700 Label push_argument_holes, push_frame; 4729 Label push_argument_holes, push_frame;
4701 __ Bind(&push_argument_holes); 4730 __ Bind(&push_argument_holes);
4702 __ Subs(w10, w10, 1); 4731 __ Subs(w10, w10, 1);
4703 __ B(mi, &push_frame); 4732 __ B(mi, &push_frame);
4704 __ Push(the_hole); 4733 __ Push(the_hole);
4705 __ B(&push_argument_holes); 4734 __ B(&push_argument_holes);
4706 4735
4707 // Enter a new JavaScript frame, and initialize its slots as they were when 4736 // Enter a new JavaScript frame, and initialize its slots as they were when
4708 // the generator was suspended. 4737 // the generator was suspended.
4709 Label resume_frame; 4738 Label resume_frame;
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
4964 return previous_; 4993 return previous_;
4965 } 4994 }
4966 4995
4967 4996
4968 #undef __ 4997 #undef __
4969 4998
4970 4999
4971 } } // namespace v8::internal 5000 } } // namespace v8::internal
4972 5001
4973 #endif // V8_TARGET_ARCH_A64 5002 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/frames-a64.cc ('k') | src/a64/ic-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698