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

Side by Side Diff: src/mips/full-codegen-mips.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/mips/codegen-mips.cc ('k') | src/mips/ic-mips.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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 info->set_prologue_offset(masm_->pc_offset()); 173 info->set_prologue_offset(masm_->pc_offset());
174 __ Prologue(BUILD_FUNCTION_FRAME); 174 __ Prologue(BUILD_FUNCTION_FRAME);
175 info->AddNoFrameRange(0, masm_->pc_offset()); 175 info->AddNoFrameRange(0, masm_->pc_offset());
176 176
177 { Comment cmnt(masm_, "[ Allocate locals"); 177 { Comment cmnt(masm_, "[ Allocate locals");
178 int locals_count = info->scope()->num_stack_slots(); 178 int locals_count = info->scope()->num_stack_slots();
179 // Generators allocate locals, if any, in context slots. 179 // Generators allocate locals, if any, in context slots.
180 ASSERT(!info->function()->is_generator() || locals_count == 0); 180 ASSERT(!info->function()->is_generator() || locals_count == 0);
181 if (locals_count > 0) { 181 if (locals_count > 0) {
182 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 182 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
183 for (int i = 0; i < locals_count; i++) { 183 // Emit a loop to initialize stack cells for locals when optimizing for
184 __ push(at); 184 // size. Otherwise, unroll the loop for maximum performance.
185 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex);
186 if (FLAG_optimize_for_size && locals_count > 4) {
187 Label loop;
188 __ li(a2, Operand(locals_count));
189 __ bind(&loop);
190 __ Subu(a2, a2, 1);
191 __ push(t5);
192 __ Branch(&loop, gt, a2, Operand(zero_reg));
193 } else {
194 for (int i = 0; i < locals_count; i++) {
195 __ push(t5);
196 }
185 } 197 }
186 } 198 }
187 } 199 }
188 200
189 bool function_in_register = true; 201 bool function_in_register = true;
190 202
191 // Possibly allocate a local context. 203 // Possibly allocate a local context.
192 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 204 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
193 if (heap_slots > 0) { 205 if (heap_slots > 0) {
194 Comment cmnt(masm_, "[ Allocate context"); 206 Comment cmnt(masm_, "[ Allocate context");
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 __ bind(&done); 624 __ bind(&done);
613 } 625 }
614 626
615 627
616 void FullCodeGenerator::StackValueContext::Plug( 628 void FullCodeGenerator::StackValueContext::Plug(
617 Label* materialize_true, 629 Label* materialize_true,
618 Label* materialize_false) const { 630 Label* materialize_false) const {
619 Label done; 631 Label done;
620 __ bind(materialize_true); 632 __ bind(materialize_true);
621 __ LoadRoot(at, Heap::kTrueValueRootIndex); 633 __ LoadRoot(at, Heap::kTrueValueRootIndex);
622 __ push(at);
623 __ Branch(&done); 634 __ Branch(&done);
624 __ bind(materialize_false); 635 __ bind(materialize_false);
625 __ LoadRoot(at, Heap::kFalseValueRootIndex); 636 __ LoadRoot(at, Heap::kFalseValueRootIndex);
637 __ bind(&done);
626 __ push(at); 638 __ push(at);
627 __ bind(&done);
628 } 639 }
629 640
630 641
631 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 642 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
632 Label* materialize_false) const { 643 Label* materialize_false) const {
633 ASSERT(materialize_true == true_label_); 644 ASSERT(materialize_true == true_label_);
634 ASSERT(materialize_false == false_label_); 645 ASSERT(materialize_false == false_label_);
635 } 646 }
636 647
637 648
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 __ jmp(&exit); 1166 __ jmp(&exit);
1156 1167
1157 // We got a fixed array in register v0. Iterate through that. 1168 // We got a fixed array in register v0. Iterate through that.
1158 Label non_proxy; 1169 Label non_proxy;
1159 __ bind(&fixed_array); 1170 __ bind(&fixed_array);
1160 1171
1161 Handle<Cell> cell = isolate()->factory()->NewCell( 1172 Handle<Cell> cell = isolate()->factory()->NewCell(
1162 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), 1173 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
1163 isolate())); 1174 isolate()));
1164 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); 1175 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
1165 __ LoadHeapObject(a1, cell); 1176 __ li(a1, cell);
1166 __ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); 1177 __ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
1167 __ sw(a2, FieldMemOperand(a1, Cell::kValueOffset)); 1178 __ sw(a2, FieldMemOperand(a1, Cell::kValueOffset));
1168 1179
1169 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check 1180 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
1170 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object 1181 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
1171 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1182 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1172 __ GetObjectType(a2, a3, a3); 1183 __ GetObjectType(a2, a3, a3);
1173 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE)); 1184 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE));
1174 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy 1185 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy
1175 __ bind(&non_proxy); 1186 __ bind(&non_proxy);
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 1609 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1599 __ mov(t1, v0); 1610 __ mov(t1, v0);
1600 1611
1601 __ bind(&materialized); 1612 __ bind(&materialized);
1602 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 1613 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
1603 Label allocated, runtime_allocate; 1614 Label allocated, runtime_allocate;
1604 __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT); 1615 __ Allocate(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT);
1605 __ jmp(&allocated); 1616 __ jmp(&allocated);
1606 1617
1607 __ bind(&runtime_allocate); 1618 __ bind(&runtime_allocate);
1608 __ push(t1);
1609 __ li(a0, Operand(Smi::FromInt(size))); 1619 __ li(a0, Operand(Smi::FromInt(size)));
1610 __ push(a0); 1620 __ Push(t1, a0);
1611 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 1621 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1612 __ pop(t1); 1622 __ pop(t1);
1613 1623
1614 __ bind(&allocated); 1624 __ bind(&allocated);
1615 1625
1616 // After this, registers are used as follows: 1626 // After this, registers are used as follows:
1617 // v0: Newly allocated regexp. 1627 // v0: Newly allocated regexp.
1618 // t1: Materialized regexp. 1628 // t1: Materialized regexp.
1619 // a2: temp. 1629 // a2: temp.
1620 __ CopyFields(v0, t1, a2.bit(), size / kPointerSize); 1630 __ CopyFields(v0, t1, a2.bit(), size / kPointerSize);
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 __ li(a1, Operand(constant_elements)); 1796 __ li(a1, Operand(constant_elements));
1787 if (has_fast_elements && constant_elements_values->map() == 1797 if (has_fast_elements && constant_elements_values->map() ==
1788 isolate()->heap()->fixed_cow_array_map()) { 1798 isolate()->heap()->fixed_cow_array_map()) {
1789 FastCloneShallowArrayStub stub( 1799 FastCloneShallowArrayStub stub(
1790 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, 1800 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
1791 DONT_TRACK_ALLOCATION_SITE, 1801 DONT_TRACK_ALLOCATION_SITE,
1792 length); 1802 length);
1793 __ CallStub(&stub); 1803 __ CallStub(&stub);
1794 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1804 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(),
1795 1, a1, a2); 1805 1, a1, a2);
1796 } else if (expr->depth() > 1) { 1806 } else if (expr->depth() > 1 ||
1807 Serializer::enabled() ||
1808 length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1797 __ Push(a3, a2, a1); 1809 __ Push(a3, a2, a1);
1798 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 1810 __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
1799 } else if (Serializer::enabled() ||
1800 length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1801 __ Push(a3, a2, a1);
1802 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
1803 } else { 1811 } else {
1804 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || 1812 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
1805 FLAG_smi_only_arrays); 1813 FLAG_smi_only_arrays);
1806 FastCloneShallowArrayStub::Mode mode = 1814 FastCloneShallowArrayStub::Mode mode =
1807 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; 1815 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
1808 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites 1816 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites
1809 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE; 1817 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE;
1810 1818
1811 if (has_fast_elements) { 1819 if (has_fast_elements) {
1812 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; 1820 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
2043 // Initial send value is undefined. 2051 // Initial send value is undefined.
2044 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 2052 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
2045 __ Branch(&l_next); 2053 __ Branch(&l_next);
2046 2054
2047 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2055 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2048 __ bind(&l_catch); 2056 __ bind(&l_catch);
2049 __ mov(a0, v0); 2057 __ mov(a0, v0);
2050 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2058 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2051 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" 2059 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
2052 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2060 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
2053 __ push(a3); // iter 2061 __ Push(a3, a0); // iter, exception
2054 __ push(a0); // exception
2055 __ jmp(&l_call); 2062 __ jmp(&l_call);
2056 2063
2057 // try { received = %yield result } 2064 // try { received = %yield result }
2058 // Shuffle the received result above a try handler and yield it without 2065 // Shuffle the received result above a try handler and yield it without
2059 // re-boxing. 2066 // re-boxing.
2060 __ bind(&l_try); 2067 __ bind(&l_try);
2061 __ pop(a0); // result 2068 __ pop(a0); // result
2062 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2069 __ PushTryHandler(StackHandler::CATCH, expr->index());
2063 const int handler_size = StackHandlerConstants::kSize; 2070 const int handler_size = StackHandlerConstants::kSize;
2064 __ push(a0); // result 2071 __ push(a0); // result
(...skipping 17 matching lines...) Expand all
2082 __ pop(v0); // result 2089 __ pop(v0); // result
2083 EmitReturnSequence(); 2090 EmitReturnSequence();
2084 __ mov(a0, v0); 2091 __ mov(a0, v0);
2085 __ bind(&l_resume); // received in a0 2092 __ bind(&l_resume); // received in a0
2086 __ PopTryHandler(); 2093 __ PopTryHandler();
2087 2094
2088 // receiver = iter; f = 'next'; arg = received; 2095 // receiver = iter; f = 'next'; arg = received;
2089 __ bind(&l_next); 2096 __ bind(&l_next);
2090 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" 2097 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
2091 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2098 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
2092 __ push(a3); // iter 2099 __ Push(a3, a0); // iter, received
2093 __ push(a0); // received
2094 2100
2095 // result = receiver[f](arg); 2101 // result = receiver[f](arg);
2096 __ bind(&l_call); 2102 __ bind(&l_call);
2097 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); 2103 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
2098 CallIC(ic); 2104 CallIC(ic);
2099 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2105 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2100 2106
2101 // if (!result.done) goto l_try; 2107 // if (!result.done) goto l_try;
2102 __ bind(&l_loop); 2108 __ bind(&l_loop);
2103 __ mov(a0, v0); 2109 __ mov(a0, v0);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 __ push(a2); 2165 __ push(a2);
2160 __ jmp(&push_argument_holes); 2166 __ jmp(&push_argument_holes);
2161 2167
2162 // Enter a new JavaScript frame, and initialize its slots as they were when 2168 // Enter a new JavaScript frame, and initialize its slots as they were when
2163 // the generator was suspended. 2169 // the generator was suspended.
2164 Label resume_frame; 2170 Label resume_frame;
2165 __ bind(&push_frame); 2171 __ bind(&push_frame);
2166 __ Call(&resume_frame); 2172 __ Call(&resume_frame);
2167 __ jmp(&done); 2173 __ jmp(&done);
2168 __ bind(&resume_frame); 2174 __ bind(&resume_frame);
2169 __ push(ra); // Return address. 2175 // ra = return address.
2170 __ push(fp); // Caller's frame pointer. 2176 // fp = caller's frame pointer.
2171 __ mov(fp, sp); 2177 // cp = callee's context,
2172 __ push(cp); // Callee's context. 2178 // t0 = callee's JS function.
2173 __ push(t0); // Callee's JS Function. 2179 __ Push(ra, fp, cp, t0);
2180 // Adjust FP to point to saved FP.
2181 __ Addu(fp, sp, 2 * kPointerSize);
2174 2182
2175 // Load the operand stack size. 2183 // Load the operand stack size.
2176 __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset)); 2184 __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset));
2177 __ lw(a3, FieldMemOperand(a3, FixedArray::kLengthOffset)); 2185 __ lw(a3, FieldMemOperand(a3, FixedArray::kLengthOffset));
2178 __ SmiUntag(a3); 2186 __ SmiUntag(a3);
2179 2187
2180 // If we are sending a value and there is no operand stack, we can jump back 2188 // If we are sending a value and there is no operand stack, we can jump back
2181 // in directly. 2189 // in directly.
2182 if (resume_mode == JSGeneratorObject::NEXT) { 2190 if (resume_mode == JSGeneratorObject::NEXT) {
2183 Label slow_resume; 2191 Label slow_resume;
(...skipping 10 matching lines...) Expand all
2194 2202
2195 // Otherwise, we push holes for the operand stack and call the runtime to fix 2203 // Otherwise, we push holes for the operand stack and call the runtime to fix
2196 // up the stack and the handlers. 2204 // up the stack and the handlers.
2197 Label push_operand_holes, call_resume; 2205 Label push_operand_holes, call_resume;
2198 __ bind(&push_operand_holes); 2206 __ bind(&push_operand_holes);
2199 __ Subu(a3, a3, Operand(1)); 2207 __ Subu(a3, a3, Operand(1));
2200 __ Branch(&call_resume, lt, a3, Operand(zero_reg)); 2208 __ Branch(&call_resume, lt, a3, Operand(zero_reg));
2201 __ push(a2); 2209 __ push(a2);
2202 __ Branch(&push_operand_holes); 2210 __ Branch(&push_operand_holes);
2203 __ bind(&call_resume); 2211 __ bind(&call_resume);
2204 __ push(a1); 2212 ASSERT(!result_register().is(a1));
2205 __ push(result_register()); 2213 __ Push(a1, result_register());
2206 __ Push(Smi::FromInt(resume_mode)); 2214 __ Push(Smi::FromInt(resume_mode));
2207 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2215 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2208 // Not reached: the runtime call returns elsewhere. 2216 // Not reached: the runtime call returns elsewhere.
2209 __ stop("not-reached"); 2217 __ stop("not-reached");
2210 2218
2211 // Throw error if we attempt to operate on a running generator. 2219 // Throw error if we attempt to operate on a running generator.
2212 __ bind(&wrong_state); 2220 __ bind(&wrong_state);
2213 __ push(a1); 2221 __ push(a1);
2214 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2222 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2215 2223
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
2425 ? isolate()->builtins()->StoreIC_Initialize() 2433 ? isolate()->builtins()->StoreIC_Initialize()
2426 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2434 : isolate()->builtins()->StoreIC_Initialize_Strict();
2427 CallIC(ic); 2435 CallIC(ic);
2428 break; 2436 break;
2429 } 2437 }
2430 case KEYED_PROPERTY: { 2438 case KEYED_PROPERTY: {
2431 __ push(result_register()); // Preserve value. 2439 __ push(result_register()); // Preserve value.
2432 VisitForStackValue(prop->obj()); 2440 VisitForStackValue(prop->obj());
2433 VisitForAccumulatorValue(prop->key()); 2441 VisitForAccumulatorValue(prop->key());
2434 __ mov(a1, result_register()); 2442 __ mov(a1, result_register());
2435 __ pop(a2); 2443 __ Pop(a0, a2); // a0 = restored value.
2436 __ pop(a0); // Restore value.
2437 Handle<Code> ic = is_classic_mode() 2444 Handle<Code> ic = is_classic_mode()
2438 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2445 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2439 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2446 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2440 CallIC(ic); 2447 CallIC(ic);
2441 break; 2448 break;
2442 } 2449 }
2443 } 2450 }
2444 context()->Plug(v0); 2451 context()->Plug(v0);
2445 } 2452 }
2446 2453
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 // Assignment to a property, using a keyed store IC. 2575 // Assignment to a property, using a keyed store IC.
2569 2576
2570 // Record source code position before IC call. 2577 // Record source code position before IC call.
2571 SetSourcePosition(expr->position()); 2578 SetSourcePosition(expr->position());
2572 // Call keyed store IC. 2579 // Call keyed store IC.
2573 // The arguments are: 2580 // The arguments are:
2574 // - a0 is the value, 2581 // - a0 is the value,
2575 // - a1 is the key, 2582 // - a1 is the key,
2576 // - a2 is the receiver. 2583 // - a2 is the receiver.
2577 __ mov(a0, result_register()); 2584 __ mov(a0, result_register());
2578 __ pop(a1); // Key. 2585 __ Pop(a2, a1); // a1 = key.
2579 __ pop(a2);
2580 2586
2581 Handle<Code> ic = is_classic_mode() 2587 Handle<Code> ic = is_classic_mode()
2582 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2588 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2583 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2589 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2584 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); 2590 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
2585 2591
2586 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2592 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2587 context()->Plug(v0); 2593 context()->Plug(v0);
2588 } 2594 }
2589 2595
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2697 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2703 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2698 __ CallStub(&stub, expr->CallFeedbackId()); 2704 __ CallStub(&stub, expr->CallFeedbackId());
2699 RecordJSReturnSite(expr); 2705 RecordJSReturnSite(expr);
2700 // Restore context register. 2706 // Restore context register.
2701 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2707 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2702 context()->DropAndPlug(1, v0); 2708 context()->DropAndPlug(1, v0);
2703 } 2709 }
2704 2710
2705 2711
2706 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2712 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2707 // Push copy of the first argument or undefined if it doesn't exist. 2713 // t2: copy of the first argument or undefined if it doesn't exist.
2708 if (arg_count > 0) { 2714 if (arg_count > 0) {
2709 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2715 __ lw(t2, MemOperand(sp, arg_count * kPointerSize));
2710 } else { 2716 } else {
2711 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); 2717 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex);
2712 } 2718 }
2713 __ push(a1);
2714 2719
2715 // Push the receiver of the enclosing function. 2720 // t1: the receiver of the enclosing function.
2716 int receiver_offset = 2 + info_->scope()->num_parameters(); 2721 int receiver_offset = 2 + info_->scope()->num_parameters();
2717 __ lw(a1, MemOperand(fp, receiver_offset * kPointerSize)); 2722 __ lw(t1, MemOperand(fp, receiver_offset * kPointerSize));
2718 __ push(a1);
2719 // Push the language mode.
2720 __ li(a1, Operand(Smi::FromInt(language_mode())));
2721 __ push(a1);
2722 2723
2723 // Push the start position of the scope the calls resides in. 2724 // t0: the language mode.
2725 __ li(t0, Operand(Smi::FromInt(language_mode())));
2726
2727 // a1: the start position of the scope the calls resides in.
2724 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); 2728 __ li(a1, Operand(Smi::FromInt(scope()->start_position())));
2725 __ push(a1);
2726 2729
2727 // Do the runtime call. 2730 // Do the runtime call.
2731 __ Push(t2, t1, t0, a1);
2728 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2732 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2729 } 2733 }
2730 2734
2731 2735
2732 void FullCodeGenerator::VisitCall(Call* expr) { 2736 void FullCodeGenerator::VisitCall(Call* expr) {
2733 #ifdef DEBUG 2737 #ifdef DEBUG
2734 // We want to verify that RecordJSReturnSite gets called on all paths 2738 // We want to verify that RecordJSReturnSite gets called on all paths
2735 // through this function. Avoid early returns. 2739 // through this function. Avoid early returns.
2736 expr->return_is_recorded_ = false; 2740 expr->return_is_recorded_ = false;
2737 #endif 2741 #endif
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2790 2794
2791 { PreservePositionScope scope(masm()->positions_recorder()); 2795 { PreservePositionScope scope(masm()->positions_recorder());
2792 // Generate code for loading from variables potentially shadowed 2796 // Generate code for loading from variables potentially shadowed
2793 // by eval-introduced variables. 2797 // by eval-introduced variables.
2794 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2798 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2795 } 2799 }
2796 2800
2797 __ bind(&slow); 2801 __ bind(&slow);
2798 // Call the runtime to find the function to call (returned in v0) 2802 // Call the runtime to find the function to call (returned in v0)
2799 // and the object holding it (returned in v1). 2803 // and the object holding it (returned in v1).
2800 __ push(context_register()); 2804 ASSERT(!context_register().is(a2));
2801 __ li(a2, Operand(proxy->name())); 2805 __ li(a2, Operand(proxy->name()));
2802 __ push(a2); 2806 __ Push(context_register(), a2);
2803 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2807 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2804 __ Push(v0, v1); // Function, receiver. 2808 __ Push(v0, v1); // Function, receiver.
2805 2809
2806 // If fast case code has been generated, emit code to push the 2810 // If fast case code has been generated, emit code to push the
2807 // function and receiver and have the slow path jump around this 2811 // function and receiver and have the slow path jump around this
2808 // code. 2812 // code.
2809 if (done.is_linked()) { 2813 if (done.is_linked()) {
2810 Label call; 2814 Label call;
2811 __ Branch(&call); 2815 __ Branch(&call);
2812 __ bind(&done); 2816 __ bind(&done);
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
3504 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { 3508 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
3505 ZoneList<Expression*>* args = expr->arguments(); 3509 ZoneList<Expression*>* args = expr->arguments();
3506 ASSERT_EQ(3, args->length()); 3510 ASSERT_EQ(3, args->length());
3507 3511
3508 Register string = v0; 3512 Register string = v0;
3509 Register index = a1; 3513 Register index = a1;
3510 Register value = a2; 3514 Register value = a2;
3511 3515
3512 VisitForStackValue(args->at(1)); // index 3516 VisitForStackValue(args->at(1)); // index
3513 VisitForStackValue(args->at(2)); // value 3517 VisitForStackValue(args->at(2)); // value
3514 __ pop(value); 3518 __ Pop(index, value);
3515 __ pop(index);
3516 VisitForAccumulatorValue(args->at(0)); // string 3519 VisitForAccumulatorValue(args->at(0)); // string
3517 3520
3518 if (FLAG_debug_code) { 3521 if (FLAG_debug_code) {
3519 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3522 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3520 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); 3523 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
3521 } 3524 }
3522 3525
3523 __ SmiUntag(value, value); 3526 __ SmiUntag(value, value);
3524 __ Addu(at, 3527 __ Addu(at,
3525 string, 3528 string,
3526 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3529 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3527 __ SmiUntag(index); 3530 __ SmiUntag(index);
3528 __ Addu(at, at, index); 3531 __ Addu(at, at, index);
3529 __ sb(value, MemOperand(at)); 3532 __ sb(value, MemOperand(at));
3530 context()->Plug(string); 3533 context()->Plug(string);
3531 } 3534 }
3532 3535
3533 3536
3534 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { 3537 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
3535 ZoneList<Expression*>* args = expr->arguments(); 3538 ZoneList<Expression*>* args = expr->arguments();
3536 ASSERT_EQ(3, args->length()); 3539 ASSERT_EQ(3, args->length());
3537 3540
3538 Register string = v0; 3541 Register string = v0;
3539 Register index = a1; 3542 Register index = a1;
3540 Register value = a2; 3543 Register value = a2;
3541 3544
3542 VisitForStackValue(args->at(1)); // index 3545 VisitForStackValue(args->at(1)); // index
3543 VisitForStackValue(args->at(2)); // value 3546 VisitForStackValue(args->at(2)); // value
3544 __ pop(value); 3547 __ Pop(index, value);
3545 __ pop(index);
3546 VisitForAccumulatorValue(args->at(0)); // string 3548 VisitForAccumulatorValue(args->at(0)); // string
3547 3549
3548 if (FLAG_debug_code) { 3550 if (FLAG_debug_code) {
3549 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3551 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3550 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3552 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
3551 } 3553 }
3552 3554
3553 __ SmiUntag(value, value); 3555 __ SmiUntag(value, value);
3554 __ Addu(at, 3556 __ Addu(at,
3555 string, 3557 string,
(...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after
4296 __ Push(a2, a1, a0); 4298 __ Push(a2, a1, a0);
4297 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4299 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4298 context()->Plug(v0); 4300 context()->Plug(v0);
4299 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4301 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4300 // Result of deleting non-global, non-dynamic variables is false. 4302 // Result of deleting non-global, non-dynamic variables is false.
4301 // The subexpression does not have side effects. 4303 // The subexpression does not have side effects.
4302 context()->Plug(var->is_this()); 4304 context()->Plug(var->is_this());
4303 } else { 4305 } else {
4304 // Non-global variable. Call the runtime to try to delete from the 4306 // Non-global variable. Call the runtime to try to delete from the
4305 // context where the variable was introduced. 4307 // context where the variable was introduced.
4306 __ push(context_register()); 4308 ASSERT(!context_register().is(a2));
4307 __ li(a2, Operand(var->name())); 4309 __ li(a2, Operand(var->name()));
4308 __ push(a2); 4310 __ Push(context_register(), a2);
4309 __ CallRuntime(Runtime::kDeleteContextSlot, 2); 4311 __ CallRuntime(Runtime::kDeleteContextSlot, 2);
4310 context()->Plug(v0); 4312 context()->Plug(v0);
4311 } 4313 }
4312 } else { 4314 } else {
4313 // Result of deleting non-property, non-variable reference is true. 4315 // Result of deleting non-property, non-variable reference is true.
4314 // The subexpression may have side effects. 4316 // The subexpression may have side effects.
4315 VisitForEffect(expr->expression()); 4317 VisitForEffect(expr->expression());
4316 context()->Plug(true); 4318 context()->Plug(true);
4317 } 4319 }
4318 break; 4320 break;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
4530 if (!context()->IsEffect()) { 4532 if (!context()->IsEffect()) {
4531 context()->PlugTOS(); 4533 context()->PlugTOS();
4532 } 4534 }
4533 } else { 4535 } else {
4534 context()->Plug(v0); 4536 context()->Plug(v0);
4535 } 4537 }
4536 break; 4538 break;
4537 } 4539 }
4538 case KEYED_PROPERTY: { 4540 case KEYED_PROPERTY: {
4539 __ mov(a0, result_register()); // Value. 4541 __ mov(a0, result_register()); // Value.
4540 __ pop(a1); // Key. 4542 __ Pop(a2, a1); // a1 = key, a2 = receiver.
4541 __ pop(a2); // Receiver.
4542 Handle<Code> ic = is_classic_mode() 4543 Handle<Code> ic = is_classic_mode()
4543 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4544 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4544 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4545 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4545 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); 4546 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
4546 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4547 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4547 if (expr->is_postfix()) { 4548 if (expr->is_postfix()) {
4548 if (!context()->IsEffect()) { 4549 if (!context()->IsEffect()) {
4549 context()->PlugTOS(); 4550 context()->PlugTOS();
4550 } 4551 }
4551 } else { 4552 } else {
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
4993 Assembler::target_address_at(pc_immediate_load_address)) == 4994 Assembler::target_address_at(pc_immediate_load_address)) ==
4994 reinterpret_cast<uint32_t>( 4995 reinterpret_cast<uint32_t>(
4995 isolate->builtins()->OsrAfterStackCheck()->entry())); 4996 isolate->builtins()->OsrAfterStackCheck()->entry()));
4996 return OSR_AFTER_STACK_CHECK; 4997 return OSR_AFTER_STACK_CHECK;
4997 } 4998 }
4998 4999
4999 5000
5000 } } // namespace v8::internal 5001 } } // namespace v8::internal
5001 5002
5002 #endif // V8_TARGET_ARCH_MIPS 5003 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/codegen-mips.cc ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698