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

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

Issue 153923005: A64: Synchronize with r17525. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/arm/codegen-arm.cc ('k') | src/arm/ic-arm.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 161
162 info->set_prologue_offset(masm_->pc_offset()); 162 info->set_prologue_offset(masm_->pc_offset());
163 __ Prologue(BUILD_FUNCTION_FRAME); 163 __ Prologue(BUILD_FUNCTION_FRAME);
164 info->AddNoFrameRange(0, masm_->pc_offset()); 164 info->AddNoFrameRange(0, masm_->pc_offset());
165 165
166 { Comment cmnt(masm_, "[ Allocate locals"); 166 { Comment cmnt(masm_, "[ Allocate locals");
167 int locals_count = info->scope()->num_stack_slots(); 167 int locals_count = info->scope()->num_stack_slots();
168 // Generators allocate locals, if any, in context slots. 168 // Generators allocate locals, if any, in context slots.
169 ASSERT(!info->function()->is_generator() || locals_count == 0); 169 ASSERT(!info->function()->is_generator() || locals_count == 0);
170 if (locals_count > 0) { 170 if (locals_count > 0) {
171 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 171 // Emit a loop to initialize stack cells for locals when optimizing for
172 for (int i = 0; i < locals_count; i++) { 172 // size. Otherwise, unroll the loop for maximum performance.
173 __ push(ip); 173 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
174 if (FLAG_optimize_for_size && locals_count > 4) {
175 Label loop;
176 __ mov(r2, Operand(locals_count));
177 __ bind(&loop);
178 __ sub(r2, r2, Operand(1), SetCC);
179 __ push(r9);
180 __ b(&loop, ne);
181 } else {
182 for (int i = 0; i < locals_count; i++) {
183 __ push(r9);
184 }
174 } 185 }
175 } 186 }
176 } 187 }
177 188
178 bool function_in_register = true; 189 bool function_in_register = true;
179 190
180 // Possibly allocate a local context. 191 // Possibly allocate a local context.
181 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 192 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
182 if (heap_slots > 0) { 193 if (heap_slots > 0) {
183 // Argument to NewContext is the function, which is still in r1. 194 // Argument to NewContext is the function, which is still in r1.
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 __ bind(&done); 617 __ bind(&done);
607 } 618 }
608 619
609 620
610 void FullCodeGenerator::StackValueContext::Plug( 621 void FullCodeGenerator::StackValueContext::Plug(
611 Label* materialize_true, 622 Label* materialize_true,
612 Label* materialize_false) const { 623 Label* materialize_false) const {
613 Label done; 624 Label done;
614 __ bind(materialize_true); 625 __ bind(materialize_true);
615 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 626 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
616 __ push(ip);
617 __ jmp(&done); 627 __ jmp(&done);
618 __ bind(materialize_false); 628 __ bind(materialize_false);
619 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 629 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
630 __ bind(&done);
620 __ push(ip); 631 __ push(ip);
621 __ bind(&done);
622 } 632 }
623 633
624 634
625 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 635 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
626 Label* materialize_false) const { 636 Label* materialize_false) const {
627 ASSERT(materialize_true == true_label_); 637 ASSERT(materialize_true == true_label_);
628 ASSERT(materialize_false == false_label_); 638 ASSERT(materialize_false == false_label_);
629 } 639 }
630 640
631 641
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 1600 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1591 __ mov(r5, r0); 1601 __ mov(r5, r0);
1592 1602
1593 __ bind(&materialized); 1603 __ bind(&materialized);
1594 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 1604 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
1595 Label allocated, runtime_allocate; 1605 Label allocated, runtime_allocate;
1596 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); 1606 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT);
1597 __ jmp(&allocated); 1607 __ jmp(&allocated);
1598 1608
1599 __ bind(&runtime_allocate); 1609 __ bind(&runtime_allocate);
1600 __ push(r5);
1601 __ mov(r0, Operand(Smi::FromInt(size))); 1610 __ mov(r0, Operand(Smi::FromInt(size)));
1602 __ push(r0); 1611 __ Push(r5, r0);
1603 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 1612 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1604 __ pop(r5); 1613 __ pop(r5);
1605 1614
1606 __ bind(&allocated); 1615 __ bind(&allocated);
1607 // After this, registers are used as follows: 1616 // After this, registers are used as follows:
1608 // r0: Newly allocated regexp. 1617 // r0: Newly allocated regexp.
1609 // r5: Materialized regexp. 1618 // r5: Materialized regexp.
1610 // r2: temp. 1619 // r2: temp.
1611 __ CopyFields(r0, r5, d0, size / kPointerSize); 1620 __ CopyFields(r0, r5, d0, size / kPointerSize);
1612 context()->Plug(r0); 1621 context()->Plug(r0);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1774 __ mov(r1, Operand(constant_elements)); 1783 __ mov(r1, Operand(constant_elements));
1775 if (has_fast_elements && constant_elements_values->map() == 1784 if (has_fast_elements && constant_elements_values->map() ==
1776 isolate()->heap()->fixed_cow_array_map()) { 1785 isolate()->heap()->fixed_cow_array_map()) {
1777 FastCloneShallowArrayStub stub( 1786 FastCloneShallowArrayStub stub(
1778 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, 1787 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
1779 DONT_TRACK_ALLOCATION_SITE, 1788 DONT_TRACK_ALLOCATION_SITE,
1780 length); 1789 length);
1781 __ CallStub(&stub); 1790 __ CallStub(&stub);
1782 __ IncrementCounter( 1791 __ IncrementCounter(
1783 isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2); 1792 isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2);
1784 } else if (expr->depth() > 1) { 1793 } else if (expr->depth() > 1 ||
1794 Serializer::enabled() ||
1795 length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1785 __ Push(r3, r2, r1); 1796 __ Push(r3, r2, r1);
1786 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 1797 __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
1787 } else if (Serializer::enabled() ||
1788 length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1789 __ Push(r3, r2, r1);
1790 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
1791 } else { 1798 } else {
1792 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || 1799 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
1793 FLAG_smi_only_arrays); 1800 FLAG_smi_only_arrays);
1794 FastCloneShallowArrayStub::Mode mode = 1801 FastCloneShallowArrayStub::Mode mode =
1795 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; 1802 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
1796 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites 1803 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites
1797 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE; 1804 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE;
1798 1805
1799 if (has_fast_elements) { 1806 if (has_fast_elements) {
1800 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; 1807 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2029 Label l_next, l_call, l_loop; 2036 Label l_next, l_call, l_loop;
2030 // Initial send value is undefined. 2037 // Initial send value is undefined.
2031 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 2038 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2032 __ b(&l_next); 2039 __ b(&l_next);
2033 2040
2034 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2041 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2035 __ bind(&l_catch); 2042 __ bind(&l_catch);
2036 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2043 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2037 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw" 2044 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw"
2038 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2045 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2039 __ push(r3); // iter 2046 __ Push(r3, r0); // iter, exception
2040 __ push(r0); // exception
2041 __ jmp(&l_call); 2047 __ jmp(&l_call);
2042 2048
2043 // try { received = %yield result } 2049 // try { received = %yield result }
2044 // Shuffle the received result above a try handler and yield it without 2050 // Shuffle the received result above a try handler and yield it without
2045 // re-boxing. 2051 // re-boxing.
2046 __ bind(&l_try); 2052 __ bind(&l_try);
2047 __ pop(r0); // result 2053 __ pop(r0); // result
2048 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2054 __ PushTryHandler(StackHandler::CATCH, expr->index());
2049 const int handler_size = StackHandlerConstants::kSize; 2055 const int handler_size = StackHandlerConstants::kSize;
2050 __ push(r0); // result 2056 __ push(r0); // result
(...skipping 15 matching lines...) Expand all
2066 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2072 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2067 __ pop(r0); // result 2073 __ pop(r0); // result
2068 EmitReturnSequence(); 2074 EmitReturnSequence();
2069 __ bind(&l_resume); // received in r0 2075 __ bind(&l_resume); // received in r0
2070 __ PopTryHandler(); 2076 __ PopTryHandler();
2071 2077
2072 // receiver = iter; f = 'next'; arg = received; 2078 // receiver = iter; f = 'next'; arg = received;
2073 __ bind(&l_next); 2079 __ bind(&l_next);
2074 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" 2080 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next"
2075 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2081 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2076 __ push(r3); // iter 2082 __ Push(r3, r0); // iter, received
2077 __ push(r0); // received
2078 2083
2079 // result = receiver[f](arg); 2084 // result = receiver[f](arg);
2080 __ bind(&l_call); 2085 __ bind(&l_call);
2081 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); 2086 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
2082 CallIC(ic); 2087 CallIC(ic);
2083 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2088 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2084 2089
2085 // if (!result.done) goto l_try; 2090 // if (!result.done) goto l_try;
2086 __ bind(&l_loop); 2091 __ bind(&l_loop);
2087 __ push(r0); // save result 2092 __ push(r0); // save result
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 __ push(r2); 2148 __ push(r2);
2144 __ jmp(&push_argument_holes); 2149 __ jmp(&push_argument_holes);
2145 2150
2146 // Enter a new JavaScript frame, and initialize its slots as they were when 2151 // Enter a new JavaScript frame, and initialize its slots as they were when
2147 // the generator was suspended. 2152 // the generator was suspended.
2148 Label resume_frame; 2153 Label resume_frame;
2149 __ bind(&push_frame); 2154 __ bind(&push_frame);
2150 __ bl(&resume_frame); 2155 __ bl(&resume_frame);
2151 __ jmp(&done); 2156 __ jmp(&done);
2152 __ bind(&resume_frame); 2157 __ bind(&resume_frame);
2153 __ push(lr); // Return address. 2158 // lr = return address.
2154 __ push(fp); // Caller's frame pointer. 2159 // fp = caller's frame pointer.
2155 __ mov(fp, sp); 2160 // cp = callee's context,
2156 __ push(cp); // Callee's context. 2161 // r4 = callee's JS function.
2157 __ push(r4); // Callee's JS Function. 2162 __ Push(lr, fp, cp, r4);
2163 // Adjust FP to point to saved FP.
2164 __ add(fp, sp, Operand(2 * kPointerSize));
2158 2165
2159 // Load the operand stack size. 2166 // Load the operand stack size.
2160 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset)); 2167 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset));
2161 __ ldr(r3, FieldMemOperand(r3, FixedArray::kLengthOffset)); 2168 __ ldr(r3, FieldMemOperand(r3, FixedArray::kLengthOffset));
2162 __ SmiUntag(r3); 2169 __ SmiUntag(r3);
2163 2170
2164 // If we are sending a value and there is no operand stack, we can jump back 2171 // If we are sending a value and there is no operand stack, we can jump back
2165 // in directly. 2172 // in directly.
2166 if (resume_mode == JSGeneratorObject::NEXT) { 2173 if (resume_mode == JSGeneratorObject::NEXT) {
2167 Label slow_resume; 2174 Label slow_resume;
(...skipping 11 matching lines...) Expand all
2179 2186
2180 // Otherwise, we push holes for the operand stack and call the runtime to fix 2187 // Otherwise, we push holes for the operand stack and call the runtime to fix
2181 // up the stack and the handlers. 2188 // up the stack and the handlers.
2182 Label push_operand_holes, call_resume; 2189 Label push_operand_holes, call_resume;
2183 __ bind(&push_operand_holes); 2190 __ bind(&push_operand_holes);
2184 __ sub(r3, r3, Operand(1), SetCC); 2191 __ sub(r3, r3, Operand(1), SetCC);
2185 __ b(mi, &call_resume); 2192 __ b(mi, &call_resume);
2186 __ push(r2); 2193 __ push(r2);
2187 __ b(&push_operand_holes); 2194 __ b(&push_operand_holes);
2188 __ bind(&call_resume); 2195 __ bind(&call_resume);
2189 __ push(r1); 2196 ASSERT(!result_register().is(r1));
2190 __ push(result_register()); 2197 __ Push(r1, result_register());
2191 __ Push(Smi::FromInt(resume_mode)); 2198 __ Push(Smi::FromInt(resume_mode));
2192 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2199 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2193 // Not reached: the runtime call returns elsewhere. 2200 // Not reached: the runtime call returns elsewhere.
2194 __ stop("not-reached"); 2201 __ stop("not-reached");
2195 2202
2196 // Throw error if we attempt to operate on a running generator. 2203 // Throw error if we attempt to operate on a running generator.
2197 __ bind(&wrong_state); 2204 __ bind(&wrong_state);
2198 __ push(r1); 2205 __ push(r1);
2199 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2206 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2200 2207
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
2402 ? isolate()->builtins()->StoreIC_Initialize() 2409 ? isolate()->builtins()->StoreIC_Initialize()
2403 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2410 : isolate()->builtins()->StoreIC_Initialize_Strict();
2404 CallIC(ic); 2411 CallIC(ic);
2405 break; 2412 break;
2406 } 2413 }
2407 case KEYED_PROPERTY: { 2414 case KEYED_PROPERTY: {
2408 __ push(r0); // Preserve value. 2415 __ push(r0); // Preserve value.
2409 VisitForStackValue(prop->obj()); 2416 VisitForStackValue(prop->obj());
2410 VisitForAccumulatorValue(prop->key()); 2417 VisitForAccumulatorValue(prop->key());
2411 __ mov(r1, r0); 2418 __ mov(r1, r0);
2412 __ pop(r2); 2419 __ Pop(r0, r2); // r0 = restored value.
2413 __ pop(r0); // Restore value.
2414 Handle<Code> ic = is_classic_mode() 2420 Handle<Code> ic = is_classic_mode()
2415 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2421 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2416 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2422 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2417 CallIC(ic); 2423 CallIC(ic);
2418 break; 2424 break;
2419 } 2425 }
2420 } 2426 }
2421 context()->Plug(r0); 2427 context()->Plug(r0);
2422 } 2428 }
2423 2429
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2537 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2543 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2538 context()->Plug(r0); 2544 context()->Plug(r0);
2539 } 2545 }
2540 2546
2541 2547
2542 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2548 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2543 // Assignment to a property, using a keyed store IC. 2549 // Assignment to a property, using a keyed store IC.
2544 2550
2545 // Record source code position before IC call. 2551 // Record source code position before IC call.
2546 SetSourcePosition(expr->position()); 2552 SetSourcePosition(expr->position());
2547 __ pop(r1); // Key. 2553 __ Pop(r2, r1); // r1 = key.
2548 __ pop(r2);
2549 2554
2550 Handle<Code> ic = is_classic_mode() 2555 Handle<Code> ic = is_classic_mode()
2551 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2556 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2552 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2557 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2553 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); 2558 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
2554 2559
2555 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2560 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2556 context()->Plug(r0); 2561 context()->Plug(r0);
2557 } 2562 }
2558 2563
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2667 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2672 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2668 __ CallStub(&stub, expr->CallFeedbackId()); 2673 __ CallStub(&stub, expr->CallFeedbackId());
2669 RecordJSReturnSite(expr); 2674 RecordJSReturnSite(expr);
2670 // Restore context register. 2675 // Restore context register.
2671 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2676 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2672 context()->DropAndPlug(1, r0); 2677 context()->DropAndPlug(1, r0);
2673 } 2678 }
2674 2679
2675 2680
2676 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2681 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2677 // Push copy of the first argument or undefined if it doesn't exist. 2682 // r4: copy of the first argument or undefined if it doesn't exist.
2678 if (arg_count > 0) { 2683 if (arg_count > 0) {
2679 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2684 __ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
2680 } else { 2685 } else {
2681 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2686 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
2682 } 2687 }
2683 __ push(r1);
2684 2688
2685 // Push the receiver of the enclosing function. 2689 // r3: the receiver of the enclosing function.
2686 int receiver_offset = 2 + info_->scope()->num_parameters(); 2690 int receiver_offset = 2 + info_->scope()->num_parameters();
2687 __ ldr(r1, MemOperand(fp, receiver_offset * kPointerSize)); 2691 __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize));
2688 __ push(r1);
2689 // Push the language mode.
2690 __ mov(r1, Operand(Smi::FromInt(language_mode())));
2691 __ push(r1);
2692 2692
2693 // Push the start position of the scope the calls resides in. 2693 // r2: the language mode.
2694 __ mov(r2, Operand(Smi::FromInt(language_mode())));
2695
2696 // r1: the start position of the scope the calls resides in.
2694 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); 2697 __ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
2695 __ push(r1);
2696 2698
2697 // Do the runtime call. 2699 // Do the runtime call.
2700 __ Push(r4, r3, r2, r1);
2698 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2701 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2699 } 2702 }
2700 2703
2701 2704
2702 void FullCodeGenerator::VisitCall(Call* expr) { 2705 void FullCodeGenerator::VisitCall(Call* expr) {
2703 #ifdef DEBUG 2706 #ifdef DEBUG
2704 // We want to verify that RecordJSReturnSite gets called on all paths 2707 // We want to verify that RecordJSReturnSite gets called on all paths
2705 // through this function. Avoid early returns. 2708 // through this function. Avoid early returns.
2706 expr->return_is_recorded_ = false; 2709 expr->return_is_recorded_ = false;
2707 #endif 2710 #endif
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2761 2764
2762 { PreservePositionScope scope(masm()->positions_recorder()); 2765 { PreservePositionScope scope(masm()->positions_recorder());
2763 // Generate code for loading from variables potentially shadowed 2766 // Generate code for loading from variables potentially shadowed
2764 // by eval-introduced variables. 2767 // by eval-introduced variables.
2765 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2768 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2766 } 2769 }
2767 2770
2768 __ bind(&slow); 2771 __ bind(&slow);
2769 // Call the runtime to find the function to call (returned in r0) 2772 // Call the runtime to find the function to call (returned in r0)
2770 // and the object holding it (returned in edx). 2773 // and the object holding it (returned in edx).
2771 __ push(context_register()); 2774 ASSERT(!context_register().is(r2));
2772 __ mov(r2, Operand(proxy->name())); 2775 __ mov(r2, Operand(proxy->name()));
2773 __ push(r2); 2776 __ Push(context_register(), r2);
2774 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2777 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2775 __ Push(r0, r1); // Function, receiver. 2778 __ Push(r0, r1); // Function, receiver.
2776 2779
2777 // If fast case code has been generated, emit code to push the 2780 // If fast case code has been generated, emit code to push the
2778 // function and receiver and have the slow path jump around this 2781 // function and receiver and have the slow path jump around this
2779 // code. 2782 // code.
2780 if (done.is_linked()) { 2783 if (done.is_linked()) {
2781 Label call; 2784 Label call;
2782 __ b(&call); 2785 __ b(&call);
2783 __ bind(&done); 2786 __ bind(&done);
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
3480 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { 3483 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
3481 ZoneList<Expression*>* args = expr->arguments(); 3484 ZoneList<Expression*>* args = expr->arguments();
3482 ASSERT_EQ(3, args->length()); 3485 ASSERT_EQ(3, args->length());
3483 3486
3484 Register string = r0; 3487 Register string = r0;
3485 Register index = r1; 3488 Register index = r1;
3486 Register value = r2; 3489 Register value = r2;
3487 3490
3488 VisitForStackValue(args->at(1)); // index 3491 VisitForStackValue(args->at(1)); // index
3489 VisitForStackValue(args->at(2)); // value 3492 VisitForStackValue(args->at(2)); // value
3490 __ pop(value); 3493 __ Pop(index, value);
3491 __ pop(index);
3492 VisitForAccumulatorValue(args->at(0)); // string 3494 VisitForAccumulatorValue(args->at(0)); // string
3493 3495
3494 if (FLAG_debug_code) { 3496 if (FLAG_debug_code) {
3495 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3497 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3496 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); 3498 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
3497 } 3499 }
3498 3500
3499 __ SmiUntag(value, value); 3501 __ SmiUntag(value, value);
3500 __ add(ip, 3502 __ add(ip,
3501 string, 3503 string,
3502 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3504 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3503 __ strb(value, MemOperand(ip, index, LSR, kSmiTagSize)); 3505 __ strb(value, MemOperand(ip, index, LSR, kSmiTagSize));
3504 context()->Plug(string); 3506 context()->Plug(string);
3505 } 3507 }
3506 3508
3507 3509
3508 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { 3510 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
3509 ZoneList<Expression*>* args = expr->arguments(); 3511 ZoneList<Expression*>* args = expr->arguments();
3510 ASSERT_EQ(3, args->length()); 3512 ASSERT_EQ(3, args->length());
3511 3513
3512 Register string = r0; 3514 Register string = r0;
3513 Register index = r1; 3515 Register index = r1;
3514 Register value = r2; 3516 Register value = r2;
3515 3517
3516 VisitForStackValue(args->at(1)); // index 3518 VisitForStackValue(args->at(1)); // index
3517 VisitForStackValue(args->at(2)); // value 3519 VisitForStackValue(args->at(2)); // value
3518 __ pop(value); 3520 __ Pop(index, value);
3519 __ pop(index);
3520 VisitForAccumulatorValue(args->at(0)); // string 3521 VisitForAccumulatorValue(args->at(0)); // string
3521 3522
3522 if (FLAG_debug_code) { 3523 if (FLAG_debug_code) {
3523 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3524 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3524 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3525 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
3525 } 3526 }
3526 3527
3527 __ SmiUntag(value, value); 3528 __ SmiUntag(value, value);
3528 __ add(ip, 3529 __ add(ip,
3529 string, 3530 string,
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
4253 __ Push(r2, r1, r0); 4254 __ Push(r2, r1, r0);
4254 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4255 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4255 context()->Plug(r0); 4256 context()->Plug(r0);
4256 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4257 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4257 // Result of deleting non-global, non-dynamic variables is false. 4258 // Result of deleting non-global, non-dynamic variables is false.
4258 // The subexpression does not have side effects. 4259 // The subexpression does not have side effects.
4259 context()->Plug(var->is_this()); 4260 context()->Plug(var->is_this());
4260 } else { 4261 } else {
4261 // Non-global variable. Call the runtime to try to delete from the 4262 // Non-global variable. Call the runtime to try to delete from the
4262 // context where the variable was introduced. 4263 // context where the variable was introduced.
4263 __ push(context_register()); 4264 ASSERT(!context_register().is(r2));
4264 __ mov(r2, Operand(var->name())); 4265 __ mov(r2, Operand(var->name()));
4265 __ push(r2); 4266 __ Push(context_register(), r2);
4266 __ CallRuntime(Runtime::kDeleteContextSlot, 2); 4267 __ CallRuntime(Runtime::kDeleteContextSlot, 2);
4267 context()->Plug(r0); 4268 context()->Plug(r0);
4268 } 4269 }
4269 } else { 4270 } else {
4270 // Result of deleting non-property, non-variable reference is true. 4271 // Result of deleting non-property, non-variable reference is true.
4271 // The subexpression may have side effects. 4272 // The subexpression may have side effects.
4272 VisitForEffect(expr->expression()); 4273 VisitForEffect(expr->expression());
4273 context()->Plug(true); 4274 context()->Plug(true);
4274 } 4275 }
4275 break; 4276 break;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
4485 if (expr->is_postfix()) { 4486 if (expr->is_postfix()) {
4486 if (!context()->IsEffect()) { 4487 if (!context()->IsEffect()) {
4487 context()->PlugTOS(); 4488 context()->PlugTOS();
4488 } 4489 }
4489 } else { 4490 } else {
4490 context()->Plug(r0); 4491 context()->Plug(r0);
4491 } 4492 }
4492 break; 4493 break;
4493 } 4494 }
4494 case KEYED_PROPERTY: { 4495 case KEYED_PROPERTY: {
4495 __ pop(r1); // Key. 4496 __ Pop(r2, r1); // r1 = key. r2 = receiver.
4496 __ pop(r2); // Receiver.
4497 Handle<Code> ic = is_classic_mode() 4497 Handle<Code> ic = is_classic_mode()
4498 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4498 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4499 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4499 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4500 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); 4500 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
4501 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4501 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4502 if (expr->is_postfix()) { 4502 if (expr->is_postfix()) {
4503 if (!context()->IsEffect()) { 4503 if (!context()->IsEffect()) {
4504 context()->PlugTOS(); 4504 context()->PlugTOS();
4505 } 4505 }
4506 } else { 4506 } else {
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
4959 ASSERT(Memory::uint32_at(interrupt_address_pointer) == 4959 ASSERT(Memory::uint32_at(interrupt_address_pointer) ==
4960 reinterpret_cast<uint32_t>( 4960 reinterpret_cast<uint32_t>(
4961 isolate->builtins()->OsrAfterStackCheck()->entry())); 4961 isolate->builtins()->OsrAfterStackCheck()->entry()));
4962 return OSR_AFTER_STACK_CHECK; 4962 return OSR_AFTER_STACK_CHECK;
4963 } 4963 }
4964 4964
4965 4965
4966 } } // namespace v8::internal 4966 } } // namespace v8::internal
4967 4967
4968 #endif // V8_TARGET_ARCH_ARM 4968 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698