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

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

Issue 71163006: Merge bleeding_edge r17376:17693. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Fix all.gyp Created 7 years, 1 month 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);
1621 context()->Plug(v0); 1631 context()->Plug(v0);
1622 } 1632 }
1623 1633
1624 1634
1625 void FullCodeGenerator::EmitAccessor(Expression* expression) { 1635 void FullCodeGenerator::EmitAccessor(Expression* expression) {
1626 if (expression == NULL) { 1636 if (expression == NULL) {
1627 __ LoadRoot(a1, Heap::kNullValueRootIndex); 1637 __ LoadRoot(a1, Heap::kNullValueRootIndex);
1628 __ push(a1); 1638 __ push(a1);
1629 } else { 1639 } else {
1630 VisitForStackValue(expression); 1640 VisitForStackValue(expression);
1631 } 1641 }
1632 } 1642 }
1633 1643
1634 1644
1635 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1645 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1636 Comment cmnt(masm_, "[ ObjectLiteral"); 1646 Comment cmnt(masm_, "[ ObjectLiteral");
1647
1648 int depth = 1;
1649 expr->BuildConstantProperties(isolate(), &depth);
1637 Handle<FixedArray> constant_properties = expr->constant_properties(); 1650 Handle<FixedArray> constant_properties = expr->constant_properties();
1638 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1651 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1639 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); 1652 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
1640 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); 1653 __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
1641 __ li(a1, Operand(constant_properties)); 1654 __ li(a1, Operand(constant_properties));
1642 int flags = expr->fast_elements() 1655 int flags = expr->fast_elements()
1643 ? ObjectLiteral::kFastElements 1656 ? ObjectLiteral::kFastElements
1644 : ObjectLiteral::kNoFlags; 1657 : ObjectLiteral::kNoFlags;
1645 flags |= expr->has_function() 1658 flags |= expr->has_function()
1646 ? ObjectLiteral::kHasFunction 1659 ? ObjectLiteral::kHasFunction
1647 : ObjectLiteral::kNoFlags; 1660 : ObjectLiteral::kNoFlags;
1648 __ li(a0, Operand(Smi::FromInt(flags))); 1661 __ li(a0, Operand(Smi::FromInt(flags)));
1649 int properties_count = constant_properties->length() / 2; 1662 int properties_count = constant_properties->length() / 2;
1650 if ((FLAG_track_double_fields && expr->may_store_doubles()) || 1663 if ((FLAG_track_double_fields && expr->may_store_doubles()) ||
1651 expr->depth() > 1 || Serializer::enabled() || 1664 depth > 1 || Serializer::enabled() ||
1652 flags != ObjectLiteral::kFastElements || 1665 flags != ObjectLiteral::kFastElements ||
1653 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 1666 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
1654 __ Push(a3, a2, a1, a0); 1667 __ Push(a3, a2, a1, a0);
1655 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); 1668 __ CallRuntime(Runtime::kCreateObjectLiteral, 4);
1656 } else { 1669 } else {
1657 FastCloneShallowObjectStub stub(properties_count); 1670 FastCloneShallowObjectStub stub(properties_count);
1658 __ CallStub(&stub); 1671 __ CallStub(&stub);
1659 } 1672 }
1660 1673
1661 // If result_saved is true the result is on top of the stack. If 1674 // If result_saved is true the result is on top of the stack. If
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 context()->PlugTOS(); 1773 context()->PlugTOS();
1761 } else { 1774 } else {
1762 context()->Plug(v0); 1775 context()->Plug(v0);
1763 } 1776 }
1764 } 1777 }
1765 1778
1766 1779
1767 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1780 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1768 Comment cmnt(masm_, "[ ArrayLiteral"); 1781 Comment cmnt(masm_, "[ ArrayLiteral");
1769 1782
1783 int depth = 1;
1784 expr->BuildConstantElements(isolate(), &depth);
1770 ZoneList<Expression*>* subexprs = expr->values(); 1785 ZoneList<Expression*>* subexprs = expr->values();
1771 int length = subexprs->length(); 1786 int length = subexprs->length();
1772 1787
1773 Handle<FixedArray> constant_elements = expr->constant_elements(); 1788 Handle<FixedArray> constant_elements = expr->constant_elements();
1774 ASSERT_EQ(2, constant_elements->length()); 1789 ASSERT_EQ(2, constant_elements->length());
1775 ElementsKind constant_elements_kind = 1790 ElementsKind constant_elements_kind =
1776 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); 1791 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value());
1777 bool has_fast_elements = 1792 bool has_fast_elements =
1778 IsFastObjectElementsKind(constant_elements_kind); 1793 IsFastObjectElementsKind(constant_elements_kind);
1779 Handle<FixedArrayBase> constant_elements_values( 1794 Handle<FixedArrayBase> constant_elements_values(
1780 FixedArrayBase::cast(constant_elements->get(1))); 1795 FixedArrayBase::cast(constant_elements->get(1)));
1781 1796
1782 __ mov(a0, result_register()); 1797 __ mov(a0, result_register());
1783 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1798 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1784 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); 1799 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
1785 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); 1800 __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
1786 __ li(a1, Operand(constant_elements)); 1801 __ li(a1, Operand(constant_elements));
1787 if (has_fast_elements && constant_elements_values->map() == 1802 if (has_fast_elements && constant_elements_values->map() ==
1788 isolate()->heap()->fixed_cow_array_map()) { 1803 isolate()->heap()->fixed_cow_array_map()) {
1789 FastCloneShallowArrayStub stub( 1804 FastCloneShallowArrayStub stub(
1790 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, 1805 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
1791 DONT_TRACK_ALLOCATION_SITE, 1806 DONT_TRACK_ALLOCATION_SITE,
1792 length); 1807 length);
1793 __ CallStub(&stub); 1808 __ CallStub(&stub);
1794 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1809 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(),
1795 1, a1, a2); 1810 1, a1, a2);
1796 } else if (expr->depth() > 1) { 1811 } else if (depth > 1 || Serializer::enabled() ||
1812 length > FastCloneShallowArrayStub::kMaximumClonedLength) {
1797 __ Push(a3, a2, a1); 1813 __ Push(a3, a2, a1);
1798 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 1814 __ 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 { 1815 } else {
1804 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || 1816 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
1805 FLAG_smi_only_arrays); 1817 FLAG_smi_only_arrays);
1806 FastCloneShallowArrayStub::Mode mode = 1818 FastCloneShallowArrayStub::Mode mode =
1807 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS; 1819 FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
1808 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites 1820 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites
1809 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE; 1821 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE;
1810 1822
1811 if (has_fast_elements) { 1823 if (has_fast_elements) {
1812 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; 1824 mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
2043 // Initial send value is undefined. 2055 // Initial send value is undefined.
2044 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 2056 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
2045 __ Branch(&l_next); 2057 __ Branch(&l_next);
2046 2058
2047 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2059 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2048 __ bind(&l_catch); 2060 __ bind(&l_catch);
2049 __ mov(a0, v0); 2061 __ mov(a0, v0);
2050 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2062 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2051 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" 2063 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
2052 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2064 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
2053 __ push(a3); // iter 2065 __ Push(a3, a0); // iter, exception
2054 __ push(a0); // exception
2055 __ jmp(&l_call); 2066 __ jmp(&l_call);
2056 2067
2057 // try { received = %yield result } 2068 // try { received = %yield result }
2058 // Shuffle the received result above a try handler and yield it without 2069 // Shuffle the received result above a try handler and yield it without
2059 // re-boxing. 2070 // re-boxing.
2060 __ bind(&l_try); 2071 __ bind(&l_try);
2061 __ pop(a0); // result 2072 __ pop(a0); // result
2062 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2073 __ PushTryHandler(StackHandler::CATCH, expr->index());
2063 const int handler_size = StackHandlerConstants::kSize; 2074 const int handler_size = StackHandlerConstants::kSize;
2064 __ push(a0); // result 2075 __ push(a0); // result
(...skipping 17 matching lines...) Expand all
2082 __ pop(v0); // result 2093 __ pop(v0); // result
2083 EmitReturnSequence(); 2094 EmitReturnSequence();
2084 __ mov(a0, v0); 2095 __ mov(a0, v0);
2085 __ bind(&l_resume); // received in a0 2096 __ bind(&l_resume); // received in a0
2086 __ PopTryHandler(); 2097 __ PopTryHandler();
2087 2098
2088 // receiver = iter; f = 'next'; arg = received; 2099 // receiver = iter; f = 'next'; arg = received;
2089 __ bind(&l_next); 2100 __ bind(&l_next);
2090 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" 2101 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
2091 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2102 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
2092 __ push(a3); // iter 2103 __ Push(a3, a0); // iter, received
2093 __ push(a0); // received
2094 2104
2095 // result = receiver[f](arg); 2105 // result = receiver[f](arg);
2096 __ bind(&l_call); 2106 __ bind(&l_call);
2097 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); 2107 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
2098 CallIC(ic); 2108 CallIC(ic);
2099 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2109 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2100 2110
2101 // if (!result.done) goto l_try; 2111 // if (!result.done) goto l_try;
2102 __ bind(&l_loop); 2112 __ bind(&l_loop);
2103 __ mov(a0, v0); 2113 __ mov(a0, v0);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 __ push(a2); 2169 __ push(a2);
2160 __ jmp(&push_argument_holes); 2170 __ jmp(&push_argument_holes);
2161 2171
2162 // Enter a new JavaScript frame, and initialize its slots as they were when 2172 // Enter a new JavaScript frame, and initialize its slots as they were when
2163 // the generator was suspended. 2173 // the generator was suspended.
2164 Label resume_frame; 2174 Label resume_frame;
2165 __ bind(&push_frame); 2175 __ bind(&push_frame);
2166 __ Call(&resume_frame); 2176 __ Call(&resume_frame);
2167 __ jmp(&done); 2177 __ jmp(&done);
2168 __ bind(&resume_frame); 2178 __ bind(&resume_frame);
2169 __ push(ra); // Return address. 2179 // ra = return address.
2170 __ push(fp); // Caller's frame pointer. 2180 // fp = caller's frame pointer.
2171 __ mov(fp, sp); 2181 // cp = callee's context,
2172 __ push(cp); // Callee's context. 2182 // t0 = callee's JS function.
2173 __ push(t0); // Callee's JS Function. 2183 __ Push(ra, fp, cp, t0);
2184 // Adjust FP to point to saved FP.
2185 __ Addu(fp, sp, 2 * kPointerSize);
2174 2186
2175 // Load the operand stack size. 2187 // Load the operand stack size.
2176 __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset)); 2188 __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset));
2177 __ lw(a3, FieldMemOperand(a3, FixedArray::kLengthOffset)); 2189 __ lw(a3, FieldMemOperand(a3, FixedArray::kLengthOffset));
2178 __ SmiUntag(a3); 2190 __ SmiUntag(a3);
2179 2191
2180 // If we are sending a value and there is no operand stack, we can jump back 2192 // If we are sending a value and there is no operand stack, we can jump back
2181 // in directly. 2193 // in directly.
2182 if (resume_mode == JSGeneratorObject::NEXT) { 2194 if (resume_mode == JSGeneratorObject::NEXT) {
2183 Label slow_resume; 2195 Label slow_resume;
(...skipping 10 matching lines...) Expand all
2194 2206
2195 // Otherwise, we push holes for the operand stack and call the runtime to fix 2207 // Otherwise, we push holes for the operand stack and call the runtime to fix
2196 // up the stack and the handlers. 2208 // up the stack and the handlers.
2197 Label push_operand_holes, call_resume; 2209 Label push_operand_holes, call_resume;
2198 __ bind(&push_operand_holes); 2210 __ bind(&push_operand_holes);
2199 __ Subu(a3, a3, Operand(1)); 2211 __ Subu(a3, a3, Operand(1));
2200 __ Branch(&call_resume, lt, a3, Operand(zero_reg)); 2212 __ Branch(&call_resume, lt, a3, Operand(zero_reg));
2201 __ push(a2); 2213 __ push(a2);
2202 __ Branch(&push_operand_holes); 2214 __ Branch(&push_operand_holes);
2203 __ bind(&call_resume); 2215 __ bind(&call_resume);
2204 __ push(a1); 2216 ASSERT(!result_register().is(a1));
2205 __ push(result_register()); 2217 __ Push(a1, result_register());
2206 __ Push(Smi::FromInt(resume_mode)); 2218 __ Push(Smi::FromInt(resume_mode));
2207 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2219 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2208 // Not reached: the runtime call returns elsewhere. 2220 // Not reached: the runtime call returns elsewhere.
2209 __ stop("not-reached"); 2221 __ stop("not-reached");
2210 2222
2211 // Throw error if we attempt to operate on a running generator. 2223 // Throw error if we attempt to operate on a running generator.
2212 __ bind(&wrong_state); 2224 __ bind(&wrong_state);
2213 __ push(a1); 2225 __ push(a1);
2214 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2226 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2215 2227
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
2425 ? isolate()->builtins()->StoreIC_Initialize() 2437 ? isolate()->builtins()->StoreIC_Initialize()
2426 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2438 : isolate()->builtins()->StoreIC_Initialize_Strict();
2427 CallIC(ic); 2439 CallIC(ic);
2428 break; 2440 break;
2429 } 2441 }
2430 case KEYED_PROPERTY: { 2442 case KEYED_PROPERTY: {
2431 __ push(result_register()); // Preserve value. 2443 __ push(result_register()); // Preserve value.
2432 VisitForStackValue(prop->obj()); 2444 VisitForStackValue(prop->obj());
2433 VisitForAccumulatorValue(prop->key()); 2445 VisitForAccumulatorValue(prop->key());
2434 __ mov(a1, result_register()); 2446 __ mov(a1, result_register());
2435 __ pop(a2); 2447 __ Pop(a0, a2); // a0 = restored value.
2436 __ pop(a0); // Restore value.
2437 Handle<Code> ic = is_classic_mode() 2448 Handle<Code> ic = is_classic_mode()
2438 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2449 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2439 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2450 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2440 CallIC(ic); 2451 CallIC(ic);
2441 break; 2452 break;
2442 } 2453 }
2443 } 2454 }
2444 context()->Plug(v0); 2455 context()->Plug(v0);
2445 } 2456 }
2446 2457
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 // Assignment to a property, using a keyed store IC. 2579 // Assignment to a property, using a keyed store IC.
2569 2580
2570 // Record source code position before IC call. 2581 // Record source code position before IC call.
2571 SetSourcePosition(expr->position()); 2582 SetSourcePosition(expr->position());
2572 // Call keyed store IC. 2583 // Call keyed store IC.
2573 // The arguments are: 2584 // The arguments are:
2574 // - a0 is the value, 2585 // - a0 is the value,
2575 // - a1 is the key, 2586 // - a1 is the key,
2576 // - a2 is the receiver. 2587 // - a2 is the receiver.
2577 __ mov(a0, result_register()); 2588 __ mov(a0, result_register());
2578 __ pop(a1); // Key. 2589 __ Pop(a2, a1); // a1 = key.
2579 __ pop(a2);
2580 2590
2581 Handle<Code> ic = is_classic_mode() 2591 Handle<Code> ic = is_classic_mode()
2582 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2592 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2583 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2593 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2584 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); 2594 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
2585 2595
2586 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2596 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2587 context()->Plug(v0); 2597 context()->Plug(v0);
2588 } 2598 }
2589 2599
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2697 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2707 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2698 __ CallStub(&stub, expr->CallFeedbackId()); 2708 __ CallStub(&stub, expr->CallFeedbackId());
2699 RecordJSReturnSite(expr); 2709 RecordJSReturnSite(expr);
2700 // Restore context register. 2710 // Restore context register.
2701 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2711 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2702 context()->DropAndPlug(1, v0); 2712 context()->DropAndPlug(1, v0);
2703 } 2713 }
2704 2714
2705 2715
2706 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2716 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2707 // Push copy of the first argument or undefined if it doesn't exist. 2717 // t2: copy of the first argument or undefined if it doesn't exist.
2708 if (arg_count > 0) { 2718 if (arg_count > 0) {
2709 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2719 __ lw(t2, MemOperand(sp, arg_count * kPointerSize));
2710 } else { 2720 } else {
2711 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); 2721 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex);
2712 } 2722 }
2713 __ push(a1);
2714 2723
2715 // Push the receiver of the enclosing function. 2724 // t1: the receiver of the enclosing function.
2716 int receiver_offset = 2 + info_->scope()->num_parameters(); 2725 int receiver_offset = 2 + info_->scope()->num_parameters();
2717 __ lw(a1, MemOperand(fp, receiver_offset * kPointerSize)); 2726 __ 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 2727
2723 // Push the start position of the scope the calls resides in. 2728 // t0: the language mode.
2729 __ li(t0, Operand(Smi::FromInt(language_mode())));
2730
2731 // a1: the start position of the scope the calls resides in.
2724 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); 2732 __ li(a1, Operand(Smi::FromInt(scope()->start_position())));
2725 __ push(a1);
2726 2733
2727 // Do the runtime call. 2734 // Do the runtime call.
2735 __ Push(t2, t1, t0, a1);
2728 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2736 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2729 } 2737 }
2730 2738
2731 2739
2732 void FullCodeGenerator::VisitCall(Call* expr) { 2740 void FullCodeGenerator::VisitCall(Call* expr) {
2733 #ifdef DEBUG 2741 #ifdef DEBUG
2734 // We want to verify that RecordJSReturnSite gets called on all paths 2742 // We want to verify that RecordJSReturnSite gets called on all paths
2735 // through this function. Avoid early returns. 2743 // through this function. Avoid early returns.
2736 expr->return_is_recorded_ = false; 2744 expr->return_is_recorded_ = false;
2737 #endif 2745 #endif
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2790 2798
2791 { PreservePositionScope scope(masm()->positions_recorder()); 2799 { PreservePositionScope scope(masm()->positions_recorder());
2792 // Generate code for loading from variables potentially shadowed 2800 // Generate code for loading from variables potentially shadowed
2793 // by eval-introduced variables. 2801 // by eval-introduced variables.
2794 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2802 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2795 } 2803 }
2796 2804
2797 __ bind(&slow); 2805 __ bind(&slow);
2798 // Call the runtime to find the function to call (returned in v0) 2806 // Call the runtime to find the function to call (returned in v0)
2799 // and the object holding it (returned in v1). 2807 // and the object holding it (returned in v1).
2800 __ push(context_register()); 2808 ASSERT(!context_register().is(a2));
2801 __ li(a2, Operand(proxy->name())); 2809 __ li(a2, Operand(proxy->name()));
2802 __ push(a2); 2810 __ Push(context_register(), a2);
2803 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2811 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2804 __ Push(v0, v1); // Function, receiver. 2812 __ Push(v0, v1); // Function, receiver.
2805 2813
2806 // If fast case code has been generated, emit code to push the 2814 // If fast case code has been generated, emit code to push the
2807 // function and receiver and have the slow path jump around this 2815 // function and receiver and have the slow path jump around this
2808 // code. 2816 // code.
2809 if (done.is_linked()) { 2817 if (done.is_linked()) {
2810 Label call; 2818 Label call;
2811 __ Branch(&call); 2819 __ Branch(&call);
2812 __ bind(&done); 2820 __ bind(&done);
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
3118 __ JumpIfSmi(v0, if_false); 3126 __ JumpIfSmi(v0, if_false);
3119 __ GetObjectType(v0, a1, a2); 3127 __ GetObjectType(v0, a1, a2);
3120 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3128 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3121 __ Branch(if_true, eq, a2, Operand(JS_FUNCTION_TYPE)); 3129 __ Branch(if_true, eq, a2, Operand(JS_FUNCTION_TYPE));
3122 __ Branch(if_false); 3130 __ Branch(if_false);
3123 3131
3124 context()->Plug(if_true, if_false); 3132 context()->Plug(if_true, if_false);
3125 } 3133 }
3126 3134
3127 3135
3136 void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
3137 ZoneList<Expression*>* args = expr->arguments();
3138 ASSERT(args->length() == 1);
3139
3140 VisitForAccumulatorValue(args->at(0));
3141
3142 Label materialize_true, materialize_false;
3143 Label* if_true = NULL;
3144 Label* if_false = NULL;
3145 Label* fall_through = NULL;
3146 context()->PrepareTest(&materialize_true, &materialize_false,
3147 &if_true, &if_false, &fall_through);
3148
3149 __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK);
3150 __ lw(a2, FieldMemOperand(v0, HeapNumber::kExponentOffset));
3151 __ lw(a1, FieldMemOperand(v0, HeapNumber::kMantissaOffset));
3152 __ li(t0, 0x80000000);
3153 Label not_nan;
3154 __ Branch(&not_nan, ne, a2, Operand(t0));
3155 __ mov(t0, zero_reg);
3156 __ mov(a2, a1);
3157 __ bind(&not_nan);
3158
3159 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3160 Split(eq, a2, Operand(t0), if_true, if_false, fall_through);
3161
3162 context()->Plug(if_true, if_false);
3163 }
3164
3165
3128 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { 3166 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
3129 ZoneList<Expression*>* args = expr->arguments(); 3167 ZoneList<Expression*>* args = expr->arguments();
3130 ASSERT(args->length() == 1); 3168 ASSERT(args->length() == 1);
3131 3169
3132 VisitForAccumulatorValue(args->at(0)); 3170 VisitForAccumulatorValue(args->at(0));
3133 3171
3134 Label materialize_true, materialize_false; 3172 Label materialize_true, materialize_false;
3135 Label* if_true = NULL; 3173 Label* if_true = NULL;
3136 Label* if_false = NULL; 3174 Label* if_false = NULL;
3137 Label* fall_through = NULL; 3175 Label* fall_through = NULL;
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
3504 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { 3542 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
3505 ZoneList<Expression*>* args = expr->arguments(); 3543 ZoneList<Expression*>* args = expr->arguments();
3506 ASSERT_EQ(3, args->length()); 3544 ASSERT_EQ(3, args->length());
3507 3545
3508 Register string = v0; 3546 Register string = v0;
3509 Register index = a1; 3547 Register index = a1;
3510 Register value = a2; 3548 Register value = a2;
3511 3549
3512 VisitForStackValue(args->at(1)); // index 3550 VisitForStackValue(args->at(1)); // index
3513 VisitForStackValue(args->at(2)); // value 3551 VisitForStackValue(args->at(2)); // value
3514 __ pop(value); 3552 __ Pop(index, value);
3515 __ pop(index);
3516 VisitForAccumulatorValue(args->at(0)); // string 3553 VisitForAccumulatorValue(args->at(0)); // string
3517 3554
3518 if (FLAG_debug_code) { 3555 if (FLAG_debug_code) {
3519 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3556 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3520 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); 3557 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
3521 } 3558 }
3522 3559
3523 __ SmiUntag(value, value); 3560 __ SmiUntag(value, value);
3524 __ Addu(at, 3561 __ Addu(at,
3525 string, 3562 string,
3526 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3563 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3527 __ SmiUntag(index); 3564 __ SmiUntag(index);
3528 __ Addu(at, at, index); 3565 __ Addu(at, at, index);
3529 __ sb(value, MemOperand(at)); 3566 __ sb(value, MemOperand(at));
3530 context()->Plug(string); 3567 context()->Plug(string);
3531 } 3568 }
3532 3569
3533 3570
3534 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { 3571 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
3535 ZoneList<Expression*>* args = expr->arguments(); 3572 ZoneList<Expression*>* args = expr->arguments();
3536 ASSERT_EQ(3, args->length()); 3573 ASSERT_EQ(3, args->length());
3537 3574
3538 Register string = v0; 3575 Register string = v0;
3539 Register index = a1; 3576 Register index = a1;
3540 Register value = a2; 3577 Register value = a2;
3541 3578
3542 VisitForStackValue(args->at(1)); // index 3579 VisitForStackValue(args->at(1)); // index
3543 VisitForStackValue(args->at(2)); // value 3580 VisitForStackValue(args->at(2)); // value
3544 __ pop(value); 3581 __ Pop(index, value);
3545 __ pop(index);
3546 VisitForAccumulatorValue(args->at(0)); // string 3582 VisitForAccumulatorValue(args->at(0)); // string
3547 3583
3548 if (FLAG_debug_code) { 3584 if (FLAG_debug_code) {
3549 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3585 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3550 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3586 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
3551 } 3587 }
3552 3588
3553 __ SmiUntag(value, value); 3589 __ SmiUntag(value, value);
3554 __ Addu(at, 3590 __ Addu(at,
3555 string, 3591 string,
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
3727 generator.GenerateSlow(masm_, call_helper); 3763 generator.GenerateSlow(masm_, call_helper);
3728 3764
3729 __ bind(&done); 3765 __ bind(&done);
3730 context()->Plug(result); 3766 context()->Plug(result);
3731 } 3767 }
3732 3768
3733 3769
3734 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { 3770 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
3735 ZoneList<Expression*>* args = expr->arguments(); 3771 ZoneList<Expression*>* args = expr->arguments();
3736 ASSERT_EQ(2, args->length()); 3772 ASSERT_EQ(2, args->length());
3737 VisitForStackValue(args->at(0)); 3773 if (FLAG_new_string_add) {
3738 VisitForStackValue(args->at(1)); 3774 VisitForStackValue(args->at(0));
3775 VisitForAccumulatorValue(args->at(1));
3739 3776
3740 StringAddStub stub(STRING_ADD_CHECK_BOTH); 3777 __ pop(a1);
3741 __ CallStub(&stub); 3778 NewStringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED);
3779 __ CallStub(&stub);
3780 } else {
3781 VisitForStackValue(args->at(0));
3782 VisitForStackValue(args->at(1));
3783
3784 StringAddStub stub(STRING_ADD_CHECK_BOTH);
3785 __ CallStub(&stub);
3786 }
3742 context()->Plug(v0); 3787 context()->Plug(v0);
3743 } 3788 }
3744 3789
3745 3790
3746 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { 3791 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
3747 ZoneList<Expression*>* args = expr->arguments(); 3792 ZoneList<Expression*>* args = expr->arguments();
3748 ASSERT_EQ(2, args->length()); 3793 ASSERT_EQ(2, args->length());
3749 3794
3750 VisitForStackValue(args->at(0)); 3795 VisitForStackValue(args->at(0));
3751 VisitForStackValue(args->at(1)); 3796 VisitForStackValue(args->at(1));
3752 3797
3753 StringCompareStub stub; 3798 StringCompareStub stub;
3754 __ CallStub(&stub); 3799 __ CallStub(&stub);
3755 context()->Plug(v0); 3800 context()->Plug(v0);
3756 } 3801 }
3757 3802
3758 3803
3759 void FullCodeGenerator::EmitMathSin(CallRuntime* expr) {
3760 // Load the argument on the stack and call the stub.
3761 TranscendentalCacheStub stub(TranscendentalCache::SIN,
3762 TranscendentalCacheStub::TAGGED);
3763 ZoneList<Expression*>* args = expr->arguments();
3764 ASSERT(args->length() == 1);
3765 VisitForStackValue(args->at(0));
3766 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos.
3767 __ CallStub(&stub);
3768 context()->Plug(v0);
3769 }
3770
3771
3772 void FullCodeGenerator::EmitMathCos(CallRuntime* expr) {
3773 // Load the argument on the stack and call the stub.
3774 TranscendentalCacheStub stub(TranscendentalCache::COS,
3775 TranscendentalCacheStub::TAGGED);
3776 ZoneList<Expression*>* args = expr->arguments();
3777 ASSERT(args->length() == 1);
3778 VisitForStackValue(args->at(0));
3779 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos.
3780 __ CallStub(&stub);
3781 context()->Plug(v0);
3782 }
3783
3784
3785 void FullCodeGenerator::EmitMathTan(CallRuntime* expr) {
3786 // Load the argument on the stack and call the stub.
3787 TranscendentalCacheStub stub(TranscendentalCache::TAN,
3788 TranscendentalCacheStub::TAGGED);
3789 ZoneList<Expression*>* args = expr->arguments();
3790 ASSERT(args->length() == 1);
3791 VisitForStackValue(args->at(0));
3792 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos.
3793 __ CallStub(&stub);
3794 context()->Plug(v0);
3795 }
3796
3797
3798 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) { 3804 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
3799 // Load the argument on the stack and call the stub. 3805 // Load the argument on the stack and call the stub.
3800 TranscendentalCacheStub stub(TranscendentalCache::LOG, 3806 TranscendentalCacheStub stub(TranscendentalCache::LOG,
3801 TranscendentalCacheStub::TAGGED); 3807 TranscendentalCacheStub::TAGGED);
3802 ZoneList<Expression*>* args = expr->arguments(); 3808 ZoneList<Expression*>* args = expr->arguments();
3803 ASSERT(args->length() == 1); 3809 ASSERT(args->length() == 1);
3804 VisitForStackValue(args->at(0)); 3810 VisitForStackValue(args->at(0));
3805 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos. 3811 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos.
3806 __ CallStub(&stub); 3812 __ CallStub(&stub);
3807 context()->Plug(v0); 3813 context()->Plug(v0);
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
4296 __ Push(a2, a1, a0); 4302 __ Push(a2, a1, a0);
4297 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4303 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4298 context()->Plug(v0); 4304 context()->Plug(v0);
4299 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4305 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4300 // Result of deleting non-global, non-dynamic variables is false. 4306 // Result of deleting non-global, non-dynamic variables is false.
4301 // The subexpression does not have side effects. 4307 // The subexpression does not have side effects.
4302 context()->Plug(var->is_this()); 4308 context()->Plug(var->is_this());
4303 } else { 4309 } else {
4304 // Non-global variable. Call the runtime to try to delete from the 4310 // Non-global variable. Call the runtime to try to delete from the
4305 // context where the variable was introduced. 4311 // context where the variable was introduced.
4306 __ push(context_register()); 4312 ASSERT(!context_register().is(a2));
4307 __ li(a2, Operand(var->name())); 4313 __ li(a2, Operand(var->name()));
4308 __ push(a2); 4314 __ Push(context_register(), a2);
4309 __ CallRuntime(Runtime::kDeleteContextSlot, 2); 4315 __ CallRuntime(Runtime::kDeleteContextSlot, 2);
4310 context()->Plug(v0); 4316 context()->Plug(v0);
4311 } 4317 }
4312 } else { 4318 } else {
4313 // Result of deleting non-property, non-variable reference is true. 4319 // Result of deleting non-property, non-variable reference is true.
4314 // The subexpression may have side effects. 4320 // The subexpression may have side effects.
4315 VisitForEffect(expr->expression()); 4321 VisitForEffect(expr->expression());
4316 context()->Plug(true); 4322 context()->Plug(true);
4317 } 4323 }
4318 break; 4324 break;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
4429 } 4435 }
4430 4436
4431 // We need a second deoptimization point after loading the value 4437 // We need a second deoptimization point after loading the value
4432 // in case evaluating the property load my have a side effect. 4438 // in case evaluating the property load my have a side effect.
4433 if (assign_type == VARIABLE) { 4439 if (assign_type == VARIABLE) {
4434 PrepareForBailout(expr->expression(), TOS_REG); 4440 PrepareForBailout(expr->expression(), TOS_REG);
4435 } else { 4441 } else {
4436 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4442 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
4437 } 4443 }
4438 4444
4439 // Call ToNumber only if operand is not a smi. 4445 // Inline smi case if we are in a loop.
4440 Label no_conversion; 4446 Label stub_call, done;
4447 JumpPatchSite patch_site(masm_);
4448
4449 int count_value = expr->op() == Token::INC ? 1 : -1;
4450 __ mov(a0, v0);
4441 if (ShouldInlineSmiCase(expr->op())) { 4451 if (ShouldInlineSmiCase(expr->op())) {
4442 __ JumpIfSmi(v0, &no_conversion); 4452 Label slow;
4453 patch_site.EmitJumpIfNotSmi(v0, &slow);
4454
4455 // Save result for postfix expressions.
4456 if (expr->is_postfix()) {
4457 if (!context()->IsEffect()) {
4458 // Save the result on the stack. If we have a named or keyed property
4459 // we store the result under the receiver that is currently on top
4460 // of the stack.
4461 switch (assign_type) {
4462 case VARIABLE:
4463 __ push(v0);
4464 break;
4465 case NAMED_PROPERTY:
4466 __ sw(v0, MemOperand(sp, kPointerSize));
4467 break;
4468 case KEYED_PROPERTY:
4469 __ sw(v0, MemOperand(sp, 2 * kPointerSize));
4470 break;
4471 }
4472 }
4473 }
4474
4475 Register scratch1 = a1;
4476 Register scratch2 = t0;
4477 __ li(scratch1, Operand(Smi::FromInt(count_value)));
4478 __ AdduAndCheckForOverflow(v0, v0, scratch1, scratch2);
4479 __ BranchOnNoOverflow(&done, scratch2);
4480 // Call stub. Undo operation first.
4481 __ Move(v0, a0);
4482 __ jmp(&stub_call);
4483 __ bind(&slow);
4443 } 4484 }
4444 __ mov(a0, v0);
4445 ToNumberStub convert_stub; 4485 ToNumberStub convert_stub;
4446 __ CallStub(&convert_stub); 4486 __ CallStub(&convert_stub);
4447 __ bind(&no_conversion);
4448 4487
4449 // Save result for postfix expressions. 4488 // Save result for postfix expressions.
4450 if (expr->is_postfix()) { 4489 if (expr->is_postfix()) {
4451 if (!context()->IsEffect()) { 4490 if (!context()->IsEffect()) {
4452 // Save the result on the stack. If we have a named or keyed property 4491 // Save the result on the stack. If we have a named or keyed property
4453 // we store the result under the receiver that is currently on top 4492 // we store the result under the receiver that is currently on top
4454 // of the stack. 4493 // of the stack.
4455 switch (assign_type) { 4494 switch (assign_type) {
4456 case VARIABLE: 4495 case VARIABLE:
4457 __ push(v0); 4496 __ push(v0);
4458 break; 4497 break;
4459 case NAMED_PROPERTY: 4498 case NAMED_PROPERTY:
4460 __ sw(v0, MemOperand(sp, kPointerSize)); 4499 __ sw(v0, MemOperand(sp, kPointerSize));
4461 break; 4500 break;
4462 case KEYED_PROPERTY: 4501 case KEYED_PROPERTY:
4463 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); 4502 __ sw(v0, MemOperand(sp, 2 * kPointerSize));
4464 break; 4503 break;
4465 } 4504 }
4466 } 4505 }
4467 } 4506 }
4468 __ mov(a0, result_register());
4469 4507
4470 // Inline smi case if we are in a loop. 4508 __ bind(&stub_call);
4471 Label stub_call, done; 4509 __ mov(a1, v0);
4472 JumpPatchSite patch_site(masm_);
4473
4474 int count_value = expr->op() == Token::INC ? 1 : -1;
4475 if (ShouldInlineSmiCase(expr->op())) {
4476 __ li(a1, Operand(Smi::FromInt(count_value)));
4477 __ AdduAndCheckForOverflow(v0, a0, a1, t0);
4478 __ BranchOnOverflow(&stub_call, t0); // Do stub on overflow.
4479
4480 // We could eliminate this smi check if we split the code at
4481 // the first smi check before calling ToNumber.
4482 patch_site.EmitJumpIfSmi(v0, &done);
4483 __ bind(&stub_call);
4484 }
4485 __ mov(a1, a0);
4486 __ li(a0, Operand(Smi::FromInt(count_value))); 4510 __ li(a0, Operand(Smi::FromInt(count_value)));
4487 4511
4488 // Record position before stub call. 4512 // Record position before stub call.
4489 SetSourcePosition(expr->position()); 4513 SetSourcePosition(expr->position());
4490 4514
4491 BinaryOpStub stub(Token::ADD, NO_OVERWRITE); 4515 BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
4492 CallIC(stub.GetCode(isolate()), 4516 CallIC(stub.GetCode(isolate()),
4493 RelocInfo::CODE_TARGET, 4517 RelocInfo::CODE_TARGET,
4494 expr->CountBinOpFeedbackId()); 4518 expr->CountBinOpFeedbackId());
4495 patch_site.EmitPatchInfo(); 4519 patch_site.EmitPatchInfo();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4530 if (!context()->IsEffect()) { 4554 if (!context()->IsEffect()) {
4531 context()->PlugTOS(); 4555 context()->PlugTOS();
4532 } 4556 }
4533 } else { 4557 } else {
4534 context()->Plug(v0); 4558 context()->Plug(v0);
4535 } 4559 }
4536 break; 4560 break;
4537 } 4561 }
4538 case KEYED_PROPERTY: { 4562 case KEYED_PROPERTY: {
4539 __ mov(a0, result_register()); // Value. 4563 __ mov(a0, result_register()); // Value.
4540 __ pop(a1); // Key. 4564 __ Pop(a2, a1); // a1 = key, a2 = receiver.
4541 __ pop(a2); // Receiver.
4542 Handle<Code> ic = is_classic_mode() 4565 Handle<Code> ic = is_classic_mode()
4543 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4566 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4544 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4567 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4545 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); 4568 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
4546 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4569 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4547 if (expr->is_postfix()) { 4570 if (expr->is_postfix()) {
4548 if (!context()->IsEffect()) { 4571 if (!context()->IsEffect()) {
4549 context()->PlugTOS(); 4572 context()->PlugTOS();
4550 } 4573 }
4551 } else { 4574 } else {
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
4993 Assembler::target_address_at(pc_immediate_load_address)) == 5016 Assembler::target_address_at(pc_immediate_load_address)) ==
4994 reinterpret_cast<uint32_t>( 5017 reinterpret_cast<uint32_t>(
4995 isolate->builtins()->OsrAfterStackCheck()->entry())); 5018 isolate->builtins()->OsrAfterStackCheck()->entry()));
4996 return OSR_AFTER_STACK_CHECK; 5019 return OSR_AFTER_STACK_CHECK;
4997 } 5020 }
4998 5021
4999 5022
5000 } } // namespace v8::internal 5023 } } // namespace v8::internal
5001 5024
5002 #endif // V8_TARGET_ARCH_MIPS 5025 #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