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

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

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 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/ic-mips.cc ('k') | src/mips/lithium-mips.h » ('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.7 1 // Copyright 2012 the V8 project authors. All rights reserved.7
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 GenerateDeferredCode() && 77 GenerateDeferredCode() &&
78 GenerateDeoptJumpTable() && 78 GenerateDeoptJumpTable() &&
79 GenerateSafepointTable(); 79 GenerateSafepointTable();
80 } 80 }
81 81
82 82
83 void LCodeGen::FinishCode(Handle<Code> code) { 83 void LCodeGen::FinishCode(Handle<Code> code) {
84 ASSERT(is_done()); 84 ASSERT(is_done());
85 code->set_stack_slots(GetStackSlotCount()); 85 code->set_stack_slots(GetStackSlotCount());
86 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 86 code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
87 RegisterDependentCodeForEmbeddedMaps(code); 87 if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
88 PopulateDeoptimizationData(code); 88 PopulateDeoptimizationData(code);
89 info()->CommitDependencies(code); 89 info()->CommitDependencies(code);
90 } 90 }
91 91
92 92
93 void LChunkBuilder::Abort(BailoutReason reason) { 93 void LChunkBuilder::Abort(BailoutReason reason) {
94 info()->set_bailout_reason(reason); 94 info()->set_bailout_reason(reason);
95 status_ = ABORTED; 95 status_ = ABORTED;
96 } 96 }
97 97
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); 172 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
173 frame_is_built_ = true; 173 frame_is_built_ = true;
174 info_->AddNoFrameRange(0, masm_->pc_offset()); 174 info_->AddNoFrameRange(0, masm_->pc_offset());
175 } 175 }
176 176
177 // Reserve space for the stack slots needed by the code. 177 // Reserve space for the stack slots needed by the code.
178 int slots = GetStackSlotCount(); 178 int slots = GetStackSlotCount();
179 if (slots > 0) { 179 if (slots > 0) {
180 if (FLAG_debug_code) { 180 if (FLAG_debug_code) {
181 __ Subu(sp, sp, Operand(slots * kPointerSize)); 181 __ Subu(sp, sp, Operand(slots * kPointerSize));
182 __ push(a0); 182 __ Push(a0, a1);
183 __ push(a1);
184 __ Addu(a0, sp, Operand(slots * kPointerSize)); 183 __ Addu(a0, sp, Operand(slots * kPointerSize));
185 __ li(a1, Operand(kSlotsZapValue)); 184 __ li(a1, Operand(kSlotsZapValue));
186 Label loop; 185 Label loop;
187 __ bind(&loop); 186 __ bind(&loop);
188 __ Subu(a0, a0, Operand(kPointerSize)); 187 __ Subu(a0, a0, Operand(kPointerSize));
189 __ sw(a1, MemOperand(a0, 2 * kPointerSize)); 188 __ sw(a1, MemOperand(a0, 2 * kPointerSize));
190 __ Branch(&loop, ne, a0, Operand(sp)); 189 __ Branch(&loop, ne, a0, Operand(sp));
191 __ pop(a1); 190 __ Pop(a0, a1);
192 __ pop(a0);
193 } else { 191 } else {
194 __ Subu(sp, sp, Operand(slots * kPointerSize)); 192 __ Subu(sp, sp, Operand(slots * kPointerSize));
195 } 193 }
196 } 194 }
197 195
198 if (info()->saves_caller_doubles()) { 196 if (info()->saves_caller_doubles()) {
199 SaveCallerDoubles(); 197 SaveCallerDoubles();
200 } 198 }
201 199
202 // Possibly allocate a local context. 200 // Possibly allocate a local context.
203 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 201 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
204 if (heap_slots > 0) { 202 if (heap_slots > 0) {
205 Comment(";;; Allocate local context"); 203 Comment(";;; Allocate local context");
206 // Argument to NewContext is the function, which is in a1. 204 // Argument to NewContext is the function, which is in a1.
207 __ push(a1);
208 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 205 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
209 FastNewContextStub stub(heap_slots); 206 FastNewContextStub stub(heap_slots);
210 __ CallStub(&stub); 207 __ CallStub(&stub);
211 } else { 208 } else {
209 __ push(a1);
212 __ CallRuntime(Runtime::kNewFunctionContext, 1); 210 __ CallRuntime(Runtime::kNewFunctionContext, 1);
213 } 211 }
214 RecordSafepoint(Safepoint::kNoLazyDeopt); 212 RecordSafepoint(Safepoint::kNoLazyDeopt);
215 // Context is returned in both v0 and cp. It replaces the context 213 // Context is returned in both v0. It replaces the context passed to us.
216 // passed to us. It's saved in the stack and kept live in cp. 214 // It's saved in the stack and kept live in cp.
217 __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 215 __ mov(cp, v0);
216 __ sw(v0, MemOperand(fp, StandardFrameConstants::kContextOffset));
218 // Copy any necessary parameters into the context. 217 // Copy any necessary parameters into the context.
219 int num_parameters = scope()->num_parameters(); 218 int num_parameters = scope()->num_parameters();
220 for (int i = 0; i < num_parameters; i++) { 219 for (int i = 0; i < num_parameters; i++) {
221 Variable* var = scope()->parameter(i); 220 Variable* var = scope()->parameter(i);
222 if (var->IsContextSlot()) { 221 if (var->IsContextSlot()) {
223 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 222 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
224 (num_parameters - 1 - i) * kPointerSize; 223 (num_parameters - 1 - i) * kPointerSize;
225 // Load parameter from stack. 224 // Load parameter from stack.
226 __ lw(a0, MemOperand(fp, parameter_offset)); 225 __ lw(a0, MemOperand(fp, parameter_offset));
227 // Store it in the context. 226 // Store it in the context.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 260
262 261
263 bool LCodeGen::GenerateDeferredCode() { 262 bool LCodeGen::GenerateDeferredCode() {
264 ASSERT(is_generating()); 263 ASSERT(is_generating());
265 if (deferred_.length() > 0) { 264 if (deferred_.length() > 0) {
266 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 265 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
267 LDeferredCode* code = deferred_[i]; 266 LDeferredCode* code = deferred_[i];
268 267
269 HValue* value = 268 HValue* value =
270 instructions_->at(code->instruction_index())->hydrogen_value(); 269 instructions_->at(code->instruction_index())->hydrogen_value();
271 RecordAndWritePosition(value->position()); 270 RecordAndWritePosition(
271 chunk()->graph()->SourcePositionToScriptPosition(value->position()));
272 272
273 Comment(";;; <@%d,#%d> " 273 Comment(";;; <@%d,#%d> "
274 "-------------------- Deferred %s --------------------", 274 "-------------------- Deferred %s --------------------",
275 code->instruction_index(), 275 code->instruction_index(),
276 code->instr()->hydrogen_value()->id(), 276 code->instr()->hydrogen_value()->id(),
277 code->instr()->Mnemonic()); 277 code->instr()->Mnemonic());
278 __ bind(code->entry()); 278 __ bind(code->entry());
279 if (NeedsDeferredFrame()) { 279 if (NeedsDeferredFrame()) {
280 Comment(";;; Build frame"); 280 Comment(";;; Build frame");
281 ASSERT(!frame_is_built_); 281 ASSERT(!frame_is_built_);
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 853 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
854 int length = deoptimizations_.length(); 854 int length = deoptimizations_.length();
855 if (length == 0) return; 855 if (length == 0) return;
856 Handle<DeoptimizationInputData> data = 856 Handle<DeoptimizationInputData> data =
857 factory()->NewDeoptimizationInputData(length, TENURED); 857 factory()->NewDeoptimizationInputData(length, TENURED);
858 858
859 Handle<ByteArray> translations = 859 Handle<ByteArray> translations =
860 translations_.CreateByteArray(isolate()->factory()); 860 translations_.CreateByteArray(isolate()->factory());
861 data->SetTranslationByteArray(*translations); 861 data->SetTranslationByteArray(*translations);
862 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 862 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
863 data->SetOptimizationId(Smi::FromInt(info_->optimization_id()));
864 if (info_->IsOptimizing()) {
865 // Reference to shared function info does not change between phases.
866 AllowDeferredHandleDereference allow_handle_dereference;
867 data->SetSharedFunctionInfo(*info_->shared_info());
868 } else {
869 data->SetSharedFunctionInfo(Smi::FromInt(0));
870 }
863 871
864 Handle<FixedArray> literals = 872 Handle<FixedArray> literals =
865 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 873 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
866 { AllowDeferredHandleDereference copy_handles; 874 { AllowDeferredHandleDereference copy_handles;
867 for (int i = 0; i < deoptimization_literals_.length(); i++) { 875 for (int i = 0; i < deoptimization_literals_.length(); i++) {
868 literals->set(i, *deoptimization_literals_[i]); 876 literals->set(i, *deoptimization_literals_[i]);
869 } 877 }
870 data->SetLiteralArray(*literals); 878 data->SetLiteralArray(*literals);
871 } 879 }
872 880
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 1031
1024 void LCodeGen::DoParameter(LParameter* instr) { 1032 void LCodeGen::DoParameter(LParameter* instr) {
1025 // Nothing to do. 1033 // Nothing to do.
1026 } 1034 }
1027 1035
1028 1036
1029 void LCodeGen::DoCallStub(LCallStub* instr) { 1037 void LCodeGen::DoCallStub(LCallStub* instr) {
1030 ASSERT(ToRegister(instr->context()).is(cp)); 1038 ASSERT(ToRegister(instr->context()).is(cp));
1031 ASSERT(ToRegister(instr->result()).is(v0)); 1039 ASSERT(ToRegister(instr->result()).is(v0));
1032 switch (instr->hydrogen()->major_key()) { 1040 switch (instr->hydrogen()->major_key()) {
1033 case CodeStub::RegExpConstructResult: {
1034 RegExpConstructResultStub stub;
1035 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1036 break;
1037 }
1038 case CodeStub::RegExpExec: { 1041 case CodeStub::RegExpExec: {
1039 RegExpExecStub stub; 1042 RegExpExecStub stub;
1040 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1043 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1041 break; 1044 break;
1042 } 1045 }
1043 case CodeStub::SubString: { 1046 case CodeStub::SubString: {
1044 SubStringStub stub; 1047 SubStringStub stub;
1045 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1048 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1046 break; 1049 break;
1047 } 1050 }
(...skipping 10 matching lines...) Expand all
1058 1061
1059 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 1062 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1060 GenerateOsrPrologue(); 1063 GenerateOsrPrologue();
1061 } 1064 }
1062 1065
1063 1066
1064 void LCodeGen::DoModI(LModI* instr) { 1067 void LCodeGen::DoModI(LModI* instr) {
1065 HMod* hmod = instr->hydrogen(); 1068 HMod* hmod = instr->hydrogen();
1066 HValue* left = hmod->left(); 1069 HValue* left = hmod->left();
1067 HValue* right = hmod->right(); 1070 HValue* right = hmod->right();
1068 if (hmod->HasPowerOf2Divisor()) { 1071 if (hmod->RightIsPowerOf2()) {
1069 const Register left_reg = ToRegister(instr->left()); 1072 const Register left_reg = ToRegister(instr->left());
1070 const Register result_reg = ToRegister(instr->result()); 1073 const Register result_reg = ToRegister(instr->result());
1071 1074
1072 // Note: The code below even works when right contains kMinInt. 1075 // Note: The code below even works when right contains kMinInt.
1073 int32_t divisor = Abs(right->GetInteger32Constant()); 1076 int32_t divisor = Abs(right->GetInteger32Constant());
1074 1077
1075 Label left_is_not_negative, done; 1078 Label left_is_not_negative, done;
1076 if (left->CanBeNegative()) { 1079 if (left->CanBeNegative()) {
1077 __ Branch(left_reg.is(result_reg) ? PROTECT : USE_DELAY_SLOT, 1080 __ Branch(left_reg.is(result_reg) ? PROTECT : USE_DELAY_SLOT,
1078 &left_is_not_negative, ge, left_reg, Operand(zero_reg)); 1081 &left_is_not_negative, ge, left_reg, Operand(zero_reg));
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
1648 } 1651 }
1649 1652
1650 1653
1651 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1654 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1652 Register result = ToRegister(instr->result()); 1655 Register result = ToRegister(instr->result());
1653 Register map = ToRegister(instr->value()); 1656 Register map = ToRegister(instr->value());
1654 __ EnumLength(result, map); 1657 __ EnumLength(result, map);
1655 } 1658 }
1656 1659
1657 1660
1658 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1659 Register result = ToRegister(instr->result());
1660 Register input = ToRegister(instr->value());
1661
1662 // Load map into |result|.
1663 __ lw(result, FieldMemOperand(input, HeapObject::kMapOffset));
1664 // Load the map's "bit field 2" into |result|. We only need the first byte,
1665 // but the following bit field extraction takes care of that anyway.
1666 __ lbu(result, FieldMemOperand(result, Map::kBitField2Offset));
1667 // Retrieve elements_kind from bit field 2.
1668 __ Ext(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount);
1669 }
1670
1671
1672 void LCodeGen::DoValueOf(LValueOf* instr) {
1673 Register input = ToRegister(instr->value());
1674 Register result = ToRegister(instr->result());
1675 Register map = ToRegister(instr->temp());
1676 Label done;
1677
1678 if (!instr->hydrogen()->value()->IsHeapObject()) {
1679 // If the object is a smi return the object.
1680 __ Move(result, input);
1681 __ JumpIfSmi(input, &done);
1682 }
1683
1684 // If the object is not a value type, return the object.
1685 __ GetObjectType(input, map, map);
1686 __ Branch(&done, ne, map, Operand(JS_VALUE_TYPE));
1687 __ lw(result, FieldMemOperand(input, JSValue::kValueOffset));
1688
1689 __ bind(&done);
1690 }
1691
1692
1693 void LCodeGen::DoDateField(LDateField* instr) { 1661 void LCodeGen::DoDateField(LDateField* instr) {
1694 Register object = ToRegister(instr->date()); 1662 Register object = ToRegister(instr->date());
1695 Register result = ToRegister(instr->result()); 1663 Register result = ToRegister(instr->result());
1696 Register scratch = ToRegister(instr->temp()); 1664 Register scratch = ToRegister(instr->temp());
1697 Smi* index = instr->index(); 1665 Smi* index = instr->index();
1698 Label runtime, done; 1666 Label runtime, done;
1699 ASSERT(object.is(a0)); 1667 ASSERT(object.is(a0));
1700 ASSERT(result.is(v0)); 1668 ASSERT(result.is(v0));
1701 ASSERT(!scratch.is(scratch0())); 1669 ASSERT(!scratch.is(scratch0()));
1702 ASSERT(!scratch.is(object)); 1670 ASSERT(!scratch.is(object));
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 1767
1800 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding); 1768 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
1801 if (encoding == String::ONE_BYTE_ENCODING) { 1769 if (encoding == String::ONE_BYTE_ENCODING) {
1802 __ sb(value, operand); 1770 __ sb(value, operand);
1803 } else { 1771 } else {
1804 __ sh(value, operand); 1772 __ sh(value, operand);
1805 } 1773 }
1806 } 1774 }
1807 1775
1808 1776
1809 void LCodeGen::DoThrow(LThrow* instr) {
1810 __ push(ToRegister(instr->value()));
1811 ASSERT(ToRegister(instr->context()).is(cp));
1812 CallRuntime(Runtime::kThrow, 1, instr);
1813
1814 if (FLAG_debug_code) {
1815 __ stop("Unreachable code.");
1816 }
1817 }
1818
1819
1820 void LCodeGen::DoAddI(LAddI* instr) { 1777 void LCodeGen::DoAddI(LAddI* instr) {
1821 LOperand* left = instr->left(); 1778 LOperand* left = instr->left();
1822 LOperand* right = instr->right(); 1779 LOperand* right = instr->right();
1823 LOperand* result = instr->result(); 1780 LOperand* result = instr->result();
1824 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1781 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1825 1782
1826 if (!can_overflow) { 1783 if (!can_overflow) {
1827 if (right->IsStackSlot() || right->IsArgument()) { 1784 if (right->IsStackSlot() || right->IsArgument()) {
1828 Register right_reg = EmitLoadRegister(right, at); 1785 Register right_reg = EmitLoadRegister(right, at);
1829 __ Addu(ToRegister(result), ToRegister(left), Operand(right_reg)); 1786 __ Addu(ToRegister(result), ToRegister(left), Operand(right_reg));
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
2658 __ lw(map, FieldMemOperand(object, HeapObject::kMapOffset)); 2615 __ lw(map, FieldMemOperand(object, HeapObject::kMapOffset));
2659 2616
2660 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 2617 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
2661 __ bind(deferred->map_check()); // Label for calculating code patching. 2618 __ bind(deferred->map_check()); // Label for calculating code patching.
2662 // We use Factory::the_hole_value() on purpose instead of loading from the 2619 // We use Factory::the_hole_value() on purpose instead of loading from the
2663 // root array to force relocation to be able to later patch with 2620 // root array to force relocation to be able to later patch with
2664 // the cached map. 2621 // the cached map.
2665 Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value()); 2622 Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value());
2666 __ li(at, Operand(Handle<Object>(cell))); 2623 __ li(at, Operand(Handle<Object>(cell)));
2667 __ lw(at, FieldMemOperand(at, PropertyCell::kValueOffset)); 2624 __ lw(at, FieldMemOperand(at, PropertyCell::kValueOffset));
2668 __ Branch(&cache_miss, ne, map, Operand(at)); 2625 __ BranchShort(&cache_miss, ne, map, Operand(at));
2669 // We use Factory::the_hole_value() on purpose instead of loading from the 2626 // We use Factory::the_hole_value() on purpose instead of loading from the
2670 // root array to force relocation to be able to later patch 2627 // root array to force relocation to be able to later patch
2671 // with true or false. 2628 // with true or false. The distance from map check has to be constant.
2672 __ li(result, Operand(factory()->the_hole_value()), CONSTANT_SIZE); 2629 __ li(result, Operand(factory()->the_hole_value()), CONSTANT_SIZE);
2673 __ Branch(&done); 2630 __ Branch(&done);
2674 2631
2675 // The inlined call site cache did not match. Check null and string before 2632 // The inlined call site cache did not match. Check null and string before
2676 // calling the deferred code. 2633 // calling the deferred code.
2677 __ bind(&cache_miss); 2634 __ bind(&cache_miss);
2678 // Null is not instance of anything. 2635 // Null is not instance of anything.
2679 __ LoadRoot(temp, Heap::kNullValueRootIndex); 2636 __ LoadRoot(temp, Heap::kNullValueRootIndex);
2680 __ Branch(&false_result, eq, object, Operand(temp)); 2637 __ Branch(&false_result, eq, object, Operand(temp));
2681 2638
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 __ bind(&done); 2949 __ bind(&done);
2993 } 2950 }
2994 2951
2995 2952
2996 void LCodeGen::DoLoadRoot(LLoadRoot* instr) { 2953 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
2997 Register result = ToRegister(instr->result()); 2954 Register result = ToRegister(instr->result());
2998 __ LoadRoot(result, instr->index()); 2955 __ LoadRoot(result, instr->index());
2999 } 2956 }
3000 2957
3001 2958
3002 void LCodeGen::DoLoadExternalArrayPointer(
3003 LLoadExternalArrayPointer* instr) {
3004 Register to_reg = ToRegister(instr->result());
3005 Register from_reg = ToRegister(instr->object());
3006 __ lw(to_reg, FieldMemOperand(from_reg,
3007 ExternalArray::kExternalPointerOffset));
3008 }
3009
3010
3011 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2959 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3012 Register arguments = ToRegister(instr->arguments()); 2960 Register arguments = ToRegister(instr->arguments());
3013 Register result = ToRegister(instr->result()); 2961 Register result = ToRegister(instr->result());
3014 // There are two words between the frame pointer and the last argument. 2962 // There are two words between the frame pointer and the last argument.
3015 // Subtracting from length accounts for one of them add one more. 2963 // Subtracting from length accounts for one of them add one more.
3016 if (instr->length()->IsConstantOperand()) { 2964 if (instr->length()->IsConstantOperand()) {
3017 int const_length = ToInteger32(LConstantOperand::cast(instr->length())); 2965 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3018 if (instr->index()->IsConstantOperand()) { 2966 if (instr->index()->IsConstantOperand()) {
3019 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 2967 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3020 int index = (const_length - const_index) + 1; 2968 int index = (const_length - const_index) + 1;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3067 } else { 3015 } else {
3068 key = ToRegister(instr->key()); 3016 key = ToRegister(instr->key());
3069 } 3017 }
3070 int element_size_shift = ElementsKindToShiftSize(elements_kind); 3018 int element_size_shift = ElementsKindToShiftSize(elements_kind);
3071 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 3019 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3072 ? (element_size_shift - kSmiTagSize) : element_size_shift; 3020 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3073 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) 3021 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
3074 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 3022 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
3075 : 0; 3023 : 0;
3076 3024
3077 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3025 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
3078 elements_kind == FLOAT32_ELEMENTS || 3026 elements_kind == FLOAT32_ELEMENTS ||
3079 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || 3027 elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
3080 elements_kind == FLOAT64_ELEMENTS) { 3028 elements_kind == FLOAT64_ELEMENTS) {
3081 int base_offset = 3029 int base_offset =
3082 (instr->additional_index() << element_size_shift) + additional_offset; 3030 (instr->additional_index() << element_size_shift) + additional_offset;
3083 FPURegister result = ToDoubleRegister(instr->result()); 3031 FPURegister result = ToDoubleRegister(instr->result());
3084 if (key_is_constant) { 3032 if (key_is_constant) {
3085 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); 3033 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
3086 } else { 3034 } else {
3087 __ sll(scratch0(), key, shift_size); 3035 __ sll(scratch0(), key, shift_size);
3088 __ Addu(scratch0(), scratch0(), external_pointer); 3036 __ Addu(scratch0(), scratch0(), external_pointer);
3089 } 3037 }
3090 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3038 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
3091 elements_kind == FLOAT32_ELEMENTS) { 3039 elements_kind == FLOAT32_ELEMENTS) {
3092 __ lwc1(result, MemOperand(scratch0(), base_offset)); 3040 __ lwc1(result, MemOperand(scratch0(), base_offset));
3093 __ cvt_d_s(result, result); 3041 __ cvt_d_s(result, result);
3094 } else { // loading doubles, not floats. 3042 } else { // loading doubles, not floats.
3095 __ ldc1(result, MemOperand(scratch0(), base_offset)); 3043 __ ldc1(result, MemOperand(scratch0(), base_offset));
3096 } 3044 }
3097 } else { 3045 } else {
3098 Register result = ToRegister(instr->result()); 3046 Register result = ToRegister(instr->result());
3099 MemOperand mem_operand = PrepareKeyedOperand( 3047 MemOperand mem_operand = PrepareKeyedOperand(
3100 key, external_pointer, key_is_constant, constant_key, 3048 key, external_pointer, key_is_constant, constant_key,
3101 element_size_shift, shift_size, 3049 element_size_shift, shift_size,
3102 instr->additional_index(), additional_offset); 3050 instr->additional_index(), additional_offset);
3103 switch (elements_kind) { 3051 switch (elements_kind) {
3104 case EXTERNAL_BYTE_ELEMENTS: 3052 case EXTERNAL_INT8_ELEMENTS:
3105 case INT8_ELEMENTS: 3053 case INT8_ELEMENTS:
3106 __ lb(result, mem_operand); 3054 __ lb(result, mem_operand);
3107 break; 3055 break;
3108 case EXTERNAL_PIXEL_ELEMENTS: 3056 case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
3109 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3057 case EXTERNAL_UINT8_ELEMENTS:
3110 case UINT8_ELEMENTS: 3058 case UINT8_ELEMENTS:
3111 case UINT8_CLAMPED_ELEMENTS: 3059 case UINT8_CLAMPED_ELEMENTS:
3112 __ lbu(result, mem_operand); 3060 __ lbu(result, mem_operand);
3113 break; 3061 break;
3114 case EXTERNAL_SHORT_ELEMENTS: 3062 case EXTERNAL_INT16_ELEMENTS:
3115 case INT16_ELEMENTS: 3063 case INT16_ELEMENTS:
3116 __ lh(result, mem_operand); 3064 __ lh(result, mem_operand);
3117 break; 3065 break;
3118 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3066 case EXTERNAL_UINT16_ELEMENTS:
3119 case UINT16_ELEMENTS: 3067 case UINT16_ELEMENTS:
3120 __ lhu(result, mem_operand); 3068 __ lhu(result, mem_operand);
3121 break; 3069 break;
3122 case EXTERNAL_INT_ELEMENTS: 3070 case EXTERNAL_INT32_ELEMENTS:
3123 case INT32_ELEMENTS: 3071 case INT32_ELEMENTS:
3124 __ lw(result, mem_operand); 3072 __ lw(result, mem_operand);
3125 break; 3073 break;
3126 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3074 case EXTERNAL_UINT32_ELEMENTS:
3127 case UINT32_ELEMENTS: 3075 case UINT32_ELEMENTS:
3128 __ lw(result, mem_operand); 3076 __ lw(result, mem_operand);
3129 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3077 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3130 DeoptimizeIf(Ugreater_equal, instr->environment(), 3078 DeoptimizeIf(Ugreater_equal, instr->environment(),
3131 result, Operand(0x80000000)); 3079 result, Operand(0x80000000));
3132 } 3080 }
3133 break; 3081 break;
3134 case FLOAT32_ELEMENTS: 3082 case FLOAT32_ELEMENTS:
3135 case FLOAT64_ELEMENTS: 3083 case FLOAT64_ELEMENTS:
3136 case EXTERNAL_FLOAT_ELEMENTS: 3084 case EXTERNAL_FLOAT32_ELEMENTS:
3137 case EXTERNAL_DOUBLE_ELEMENTS: 3085 case EXTERNAL_FLOAT64_ELEMENTS:
3138 case FAST_DOUBLE_ELEMENTS: 3086 case FAST_DOUBLE_ELEMENTS:
3139 case FAST_ELEMENTS: 3087 case FAST_ELEMENTS:
3140 case FAST_SMI_ELEMENTS: 3088 case FAST_SMI_ELEMENTS:
3141 case FAST_HOLEY_DOUBLE_ELEMENTS: 3089 case FAST_HOLEY_DOUBLE_ELEMENTS:
3142 case FAST_HOLEY_ELEMENTS: 3090 case FAST_HOLEY_ELEMENTS:
3143 case FAST_HOLEY_SMI_ELEMENTS: 3091 case FAST_HOLEY_SMI_ELEMENTS:
3144 case DICTIONARY_ELEMENTS: 3092 case DICTIONARY_ELEMENTS:
3145 case NON_STRICT_ARGUMENTS_ELEMENTS: 3093 case NON_STRICT_ARGUMENTS_ELEMENTS:
3146 UNREACHABLE(); 3094 UNREACHABLE();
3147 break; 3095 break;
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
3356 Register receiver = ToRegister(instr->receiver()); 3304 Register receiver = ToRegister(instr->receiver());
3357 Register function = ToRegister(instr->function()); 3305 Register function = ToRegister(instr->function());
3358 Register result = ToRegister(instr->result()); 3306 Register result = ToRegister(instr->result());
3359 Register scratch = scratch0(); 3307 Register scratch = scratch0();
3360 3308
3361 // If the receiver is null or undefined, we have to pass the global 3309 // If the receiver is null or undefined, we have to pass the global
3362 // object as a receiver to normal functions. Values have to be 3310 // object as a receiver to normal functions. Values have to be
3363 // passed unchanged to builtins and strict-mode functions. 3311 // passed unchanged to builtins and strict-mode functions.
3364 Label global_object, result_in_receiver; 3312 Label global_object, result_in_receiver;
3365 3313
3366 // Do not transform the receiver to object for strict mode 3314 if (!instr->hydrogen()->known_function()) {
3367 // functions. 3315 // Do not transform the receiver to object for strict mode
3368 __ lw(scratch, 3316 // functions.
3369 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3317 __ lw(scratch,
3370 __ lw(scratch, 3318 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
3371 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); 3319 __ lw(scratch,
3320 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset));
3372 3321
3373 // Do not transform the receiver to object for builtins. 3322 // Do not transform the receiver to object for builtins.
3374 int32_t strict_mode_function_mask = 3323 int32_t strict_mode_function_mask =
3375 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize); 3324 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize);
3376 int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize); 3325 int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize);
3377 __ And(scratch, scratch, Operand(strict_mode_function_mask | native_mask)); 3326 __ And(scratch, scratch, Operand(strict_mode_function_mask | native_mask));
3378 __ Branch(&result_in_receiver, ne, scratch, Operand(zero_reg)); 3327 __ Branch(&result_in_receiver, ne, scratch, Operand(zero_reg));
3328 }
3379 3329
3380 // Normal function. Replace undefined or null with global receiver. 3330 // Normal function. Replace undefined or null with global receiver.
3381 __ LoadRoot(scratch, Heap::kNullValueRootIndex); 3331 __ LoadRoot(scratch, Heap::kNullValueRootIndex);
3382 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3332 __ Branch(&global_object, eq, receiver, Operand(scratch));
3383 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 3333 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
3384 __ Branch(&global_object, eq, receiver, Operand(scratch)); 3334 __ Branch(&global_object, eq, receiver, Operand(scratch));
3385 3335
3386 // Deoptimize if the receiver is not a JS object. 3336 // Deoptimize if the receiver is not a JS object.
3387 __ SmiTst(receiver, scratch); 3337 __ SmiTst(receiver, scratch);
3388 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); 3338 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
3389 3339
3390 __ GetObjectType(receiver, scratch, scratch); 3340 __ GetObjectType(receiver, scratch, scratch);
3391 DeoptimizeIf(lt, instr->environment(), 3341 DeoptimizeIf(lt, instr->environment(),
3392 scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); 3342 scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
3343
3393 __ Branch(&result_in_receiver); 3344 __ Branch(&result_in_receiver);
3394
3395 __ bind(&global_object); 3345 __ bind(&global_object);
3396 __ lw(receiver, FieldMemOperand(function, JSFunction::kContextOffset)); 3346 __ lw(result, FieldMemOperand(function, JSFunction::kContextOffset));
3397 __ lw(receiver, 3347 __ lw(result,
3398 ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX)); 3348 ContextOperand(result, Context::GLOBAL_OBJECT_INDEX));
3399 __ lw(receiver, 3349 __ lw(result,
3400 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); 3350 FieldMemOperand(result, GlobalObject::kGlobalReceiverOffset));
3401 3351
3402 if (result.is(receiver)) { 3352 if (result.is(receiver)) {
3403 __ bind(&result_in_receiver); 3353 __ bind(&result_in_receiver);
3404 } else { 3354 } else {
3405 Label result_ok; 3355 Label result_ok;
3406 __ Branch(&result_ok); 3356 __ Branch(&result_ok);
3407 __ bind(&result_in_receiver); 3357 __ bind(&result_in_receiver);
3408 __ mov(result, receiver); 3358 __ mov(result, receiver);
3409 __ bind(&result_ok); 3359 __ bind(&result_ok);
3410 } 3360 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
3486 Register result = ToRegister(instr->result()); 3436 Register result = ToRegister(instr->result());
3487 if (info()->IsOptimizing()) { 3437 if (info()->IsOptimizing()) {
3488 __ lw(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3438 __ lw(result, MemOperand(fp, StandardFrameConstants::kContextOffset));
3489 } else { 3439 } else {
3490 // If there is no frame, the context must be in cp. 3440 // If there is no frame, the context must be in cp.
3491 ASSERT(result.is(cp)); 3441 ASSERT(result.is(cp));
3492 } 3442 }
3493 } 3443 }
3494 3444
3495 3445
3496 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3497 Register context = ToRegister(instr->context());
3498 Register result = ToRegister(instr->result());
3499 __ lw(result,
3500 MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3501 }
3502
3503
3504 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3446 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3505 ASSERT(ToRegister(instr->context()).is(cp)); 3447 ASSERT(ToRegister(instr->context()).is(cp));
3506 __ li(scratch0(), instr->hydrogen()->pairs()); 3448 __ li(scratch0(), instr->hydrogen()->pairs());
3507 __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); 3449 __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags())));
3508 // The context is the first argument. 3450 // The context is the first argument.
3509 __ Push(cp, scratch0(), scratch1()); 3451 __ Push(cp, scratch0(), scratch1());
3510 CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3452 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3511 } 3453 }
3512 3454
3513 3455
3514 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3515 Register context = ToRegister(instr->context());
3516 Register result = ToRegister(instr->result());
3517 __ lw(result, ContextOperand(context, Context::GLOBAL_OBJECT_INDEX));
3518 }
3519
3520
3521 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3522 Register global = ToRegister(instr->global_object());
3523 Register result = ToRegister(instr->result());
3524 __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
3525 }
3526
3527
3528 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 3456 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
3529 int formal_parameter_count, 3457 int formal_parameter_count,
3530 int arity, 3458 int arity,
3531 LInstruction* instr, 3459 LInstruction* instr,
3532 A1State a1_state) { 3460 A1State a1_state) {
3533 bool dont_adapt_arguments = 3461 bool dont_adapt_arguments =
3534 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 3462 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3535 bool can_invoke_directly = 3463 bool can_invoke_directly =
3536 dont_adapt_arguments || formal_parameter_count == arity; 3464 dont_adapt_arguments || formal_parameter_count == arity;
3537 3465
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
3829 ASSERT(ToDoubleRegister(instr->left()).is(f2)); 3757 ASSERT(ToDoubleRegister(instr->left()).is(f2));
3830 ASSERT(ToDoubleRegister(instr->result()).is(f0)); 3758 ASSERT(ToDoubleRegister(instr->result()).is(f0));
3831 3759
3832 if (exponent_type.IsSmi()) { 3760 if (exponent_type.IsSmi()) {
3833 MathPowStub stub(MathPowStub::TAGGED); 3761 MathPowStub stub(MathPowStub::TAGGED);
3834 __ CallStub(&stub); 3762 __ CallStub(&stub);
3835 } else if (exponent_type.IsTagged()) { 3763 } else if (exponent_type.IsTagged()) {
3836 Label no_deopt; 3764 Label no_deopt;
3837 __ JumpIfSmi(a2, &no_deopt); 3765 __ JumpIfSmi(a2, &no_deopt);
3838 __ lw(t3, FieldMemOperand(a2, HeapObject::kMapOffset)); 3766 __ lw(t3, FieldMemOperand(a2, HeapObject::kMapOffset));
3767 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
3839 DeoptimizeIf(ne, instr->environment(), t3, Operand(at)); 3768 DeoptimizeIf(ne, instr->environment(), t3, Operand(at));
3840 __ bind(&no_deopt); 3769 __ bind(&no_deopt);
3841 MathPowStub stub(MathPowStub::TAGGED); 3770 MathPowStub stub(MathPowStub::TAGGED);
3842 __ CallStub(&stub); 3771 __ CallStub(&stub);
3843 } else if (exponent_type.IsInteger32()) { 3772 } else if (exponent_type.IsInteger32()) {
3844 MathPowStub stub(MathPowStub::INTEGER); 3773 MathPowStub stub(MathPowStub::INTEGER);
3845 __ CallStub(&stub); 3774 __ CallStub(&stub);
3846 } else { 3775 } else {
3847 ASSERT(exponent_type.IsDouble()); 3776 ASSERT(exponent_type.IsDouble());
3848 MathPowStub stub(MathPowStub::DOUBLE); 3777 MathPowStub stub(MathPowStub::DOUBLE);
(...skipping 18 matching lines...) Expand all
3867 3796
3868 void LCodeGen::DoMathLog(LMathLog* instr) { 3797 void LCodeGen::DoMathLog(LMathLog* instr) {
3869 __ PrepareCallCFunction(0, 1, scratch0()); 3798 __ PrepareCallCFunction(0, 1, scratch0());
3870 __ MovToFloatParameter(ToDoubleRegister(instr->value())); 3799 __ MovToFloatParameter(ToDoubleRegister(instr->value()));
3871 __ CallCFunction(ExternalReference::math_log_double_function(isolate()), 3800 __ CallCFunction(ExternalReference::math_log_double_function(isolate()),
3872 0, 1); 3801 0, 1);
3873 __ MovFromFloatResult(ToDoubleRegister(instr->result())); 3802 __ MovFromFloatResult(ToDoubleRegister(instr->result()));
3874 } 3803 }
3875 3804
3876 3805
3806 void LCodeGen::DoMathClz32(LMathClz32* instr) {
3807 Register input = ToRegister(instr->value());
3808 Register result = ToRegister(instr->result());
3809 __ Clz(result, input);
3810 }
3811
3812
3877 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3813 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3878 ASSERT(ToRegister(instr->context()).is(cp)); 3814 ASSERT(ToRegister(instr->context()).is(cp));
3879 ASSERT(ToRegister(instr->function()).is(a1)); 3815 ASSERT(ToRegister(instr->function()).is(a1));
3880 ASSERT(instr->HasPointerMap()); 3816 ASSERT(instr->HasPointerMap());
3881 3817
3882 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 3818 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3883 if (known_function.is_null()) { 3819 if (known_function.is_null()) {
3884 LPointerMap* pointers = instr->pointer_map(); 3820 LPointerMap* pointers = instr->pointer_map();
3885 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3821 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3886 ParameterCount count(instr->arity()); 3822 ParameterCount count(instr->arity());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3935 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 3871 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3936 } 3872 }
3937 3873
3938 3874
3939 void LCodeGen::DoCallFunction(LCallFunction* instr) { 3875 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3940 ASSERT(ToRegister(instr->context()).is(cp)); 3876 ASSERT(ToRegister(instr->context()).is(cp));
3941 ASSERT(ToRegister(instr->function()).is(a1)); 3877 ASSERT(ToRegister(instr->function()).is(a1));
3942 ASSERT(ToRegister(instr->result()).is(v0)); 3878 ASSERT(ToRegister(instr->result()).is(v0));
3943 3879
3944 int arity = instr->arity(); 3880 int arity = instr->arity();
3945 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 3881 CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
3946 if (instr->hydrogen()->IsTailCall()) { 3882 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3947 if (NeedsEagerFrame()) __ mov(sp, fp);
3948 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
3949 } else {
3950 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3951 }
3952 } 3883 }
3953 3884
3954 3885
3955 void LCodeGen::DoCallNew(LCallNew* instr) { 3886 void LCodeGen::DoCallNew(LCallNew* instr) {
3956 ASSERT(ToRegister(instr->context()).is(cp)); 3887 ASSERT(ToRegister(instr->context()).is(cp));
3957 ASSERT(ToRegister(instr->constructor()).is(a1)); 3888 ASSERT(ToRegister(instr->constructor()).is(a1));
3958 ASSERT(ToRegister(instr->result()).is(v0)); 3889 ASSERT(ToRegister(instr->result()).is(v0));
3959 3890
3960 __ li(a0, Operand(instr->arity())); 3891 __ li(a0, Operand(instr->arity()));
3961 // No cell in a2 for construct type feedback in optimized code 3892 // No cell in a2 for construct type feedback in optimized code
3962 Handle<Object> undefined_value(isolate()->factory()->undefined_value()); 3893 Handle<Object> undefined_value(isolate()->factory()->undefined_value());
3963 __ li(a2, Operand(undefined_value)); 3894 __ li(a2, Operand(undefined_value));
3964 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 3895 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
3965 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 3896 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3966 } 3897 }
3967 3898
3968 3899
3969 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { 3900 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
3970 ASSERT(ToRegister(instr->context()).is(cp)); 3901 ASSERT(ToRegister(instr->context()).is(cp));
3971 ASSERT(ToRegister(instr->constructor()).is(a1)); 3902 ASSERT(ToRegister(instr->constructor()).is(a1));
3972 ASSERT(ToRegister(instr->result()).is(v0)); 3903 ASSERT(ToRegister(instr->result()).is(v0));
3973 3904
3974 __ li(a0, Operand(instr->arity())); 3905 __ li(a0, Operand(instr->arity()));
3975 __ li(a2, Operand(instr->hydrogen()->property_cell())); 3906 __ li(a2, Operand(factory()->undefined_value()));
3976 ElementsKind kind = instr->hydrogen()->elements_kind(); 3907 ElementsKind kind = instr->hydrogen()->elements_kind();
3977 AllocationSiteOverrideMode override_mode = 3908 AllocationSiteOverrideMode override_mode =
3978 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 3909 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
3979 ? DISABLE_ALLOCATION_SITES 3910 ? DISABLE_ALLOCATION_SITES
3980 : DONT_OVERRIDE; 3911 : DONT_OVERRIDE;
3981 3912
3982 if (instr->arity() == 0) { 3913 if (instr->arity() == 0) {
3983 ArrayNoArgumentConstructorStub stub(kind, override_mode); 3914 ArrayNoArgumentConstructorStub stub(kind, override_mode);
3984 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 3915 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3985 } else if (instr->arity() == 1) { 3916 } else if (instr->arity() == 1) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
4045 int offset = access.offset(); 3976 int offset = access.offset();
4046 3977
4047 if (access.IsExternalMemory()) { 3978 if (access.IsExternalMemory()) {
4048 Register value = ToRegister(instr->value()); 3979 Register value = ToRegister(instr->value());
4049 MemOperand operand = MemOperand(object, offset); 3980 MemOperand operand = MemOperand(object, offset);
4050 __ Store(value, operand, representation); 3981 __ Store(value, operand, representation);
4051 return; 3982 return;
4052 } 3983 }
4053 3984
4054 Handle<Map> transition = instr->transition(); 3985 Handle<Map> transition = instr->transition();
3986 SmiCheck check_needed =
3987 instr->hydrogen()->value()->IsHeapObject()
3988 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4055 3989
4056 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 3990 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
4057 Register value = ToRegister(instr->value()); 3991 Register value = ToRegister(instr->value());
4058 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 3992 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4059 __ SmiTst(value, scratch); 3993 __ SmiTst(value, scratch);
4060 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); 3994 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
3995
3996 // We know that value is a smi now, so we can omit the check below.
3997 check_needed = OMIT_SMI_CHECK;
4061 } 3998 }
4062 } else if (FLAG_track_double_fields && representation.IsDouble()) { 3999 } else if (representation.IsDouble()) {
4063 ASSERT(transition.is_null()); 4000 ASSERT(transition.is_null());
4064 ASSERT(access.IsInobject()); 4001 ASSERT(access.IsInobject());
4065 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 4002 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4066 DoubleRegister value = ToDoubleRegister(instr->value()); 4003 DoubleRegister value = ToDoubleRegister(instr->value());
4067 __ sdc1(value, FieldMemOperand(object, offset)); 4004 __ sdc1(value, FieldMemOperand(object, offset));
4068 return; 4005 return;
4069 } 4006 }
4070 4007
4071 if (!transition.is_null()) { 4008 if (!transition.is_null()) {
4072 __ li(scratch, Operand(transition)); 4009 __ li(scratch, Operand(transition));
4073 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 4010 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
4074 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { 4011 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
4075 Register temp = ToRegister(instr->temp()); 4012 Register temp = ToRegister(instr->temp());
4076 // Update the write barrier for the map field. 4013 // Update the write barrier for the map field.
4077 __ RecordWriteField(object, 4014 __ RecordWriteField(object,
4078 HeapObject::kMapOffset, 4015 HeapObject::kMapOffset,
4079 scratch, 4016 scratch,
4080 temp, 4017 temp,
4081 GetRAState(), 4018 GetRAState(),
4082 kSaveFPRegs, 4019 kSaveFPRegs,
4083 OMIT_REMEMBERED_SET, 4020 OMIT_REMEMBERED_SET,
4084 OMIT_SMI_CHECK); 4021 OMIT_SMI_CHECK);
4085 } 4022 }
4086 } 4023 }
4087 4024
4088 // Do the store. 4025 // Do the store.
4089 Register value = ToRegister(instr->value()); 4026 Register value = ToRegister(instr->value());
4090 ASSERT(!object.is(value));
4091 SmiCheck check_needed =
4092 instr->hydrogen()->value()->IsHeapObject()
4093 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4094 if (access.IsInobject()) { 4027 if (access.IsInobject()) {
4095 MemOperand operand = FieldMemOperand(object, offset); 4028 MemOperand operand = FieldMemOperand(object, offset);
4096 __ Store(value, operand, representation); 4029 __ Store(value, operand, representation);
4097 if (instr->hydrogen()->NeedsWriteBarrier()) { 4030 if (instr->hydrogen()->NeedsWriteBarrier()) {
4098 // Update the write barrier for the object for in-object properties. 4031 // Update the write barrier for the object for in-object properties.
4099 __ RecordWriteField(object, 4032 __ RecordWriteField(object,
4100 offset, 4033 offset,
4101 value, 4034 value,
4102 scratch, 4035 scratch,
4103 GetRAState(), 4036 GetRAState(),
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
4192 } else { 4125 } else {
4193 key = ToRegister(instr->key()); 4126 key = ToRegister(instr->key());
4194 } 4127 }
4195 int element_size_shift = ElementsKindToShiftSize(elements_kind); 4128 int element_size_shift = ElementsKindToShiftSize(elements_kind);
4196 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 4129 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
4197 ? (element_size_shift - kSmiTagSize) : element_size_shift; 4130 ? (element_size_shift - kSmiTagSize) : element_size_shift;
4198 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) 4131 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
4199 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 4132 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
4200 : 0; 4133 : 0;
4201 4134
4202 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4135 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
4203 elements_kind == FLOAT32_ELEMENTS || 4136 elements_kind == FLOAT32_ELEMENTS ||
4204 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || 4137 elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
4205 elements_kind == FLOAT64_ELEMENTS) { 4138 elements_kind == FLOAT64_ELEMENTS) {
4206 int base_offset = 4139 int base_offset =
4207 (instr->additional_index() << element_size_shift) + additional_offset; 4140 (instr->additional_index() << element_size_shift) + additional_offset;
4208 Register address = scratch0(); 4141 Register address = scratch0();
4209 FPURegister value(ToDoubleRegister(instr->value())); 4142 FPURegister value(ToDoubleRegister(instr->value()));
4210 if (key_is_constant) { 4143 if (key_is_constant) {
4211 if (constant_key != 0) { 4144 if (constant_key != 0) {
4212 __ Addu(address, external_pointer, 4145 __ Addu(address, external_pointer,
4213 Operand(constant_key << element_size_shift)); 4146 Operand(constant_key << element_size_shift));
4214 } else { 4147 } else {
4215 address = external_pointer; 4148 address = external_pointer;
4216 } 4149 }
4217 } else { 4150 } else {
4218 __ sll(address, key, shift_size); 4151 __ sll(address, key, shift_size);
4219 __ Addu(address, external_pointer, address); 4152 __ Addu(address, external_pointer, address);
4220 } 4153 }
4221 4154
4222 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4155 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
4223 elements_kind == FLOAT32_ELEMENTS) { 4156 elements_kind == FLOAT32_ELEMENTS) {
4224 __ cvt_s_d(double_scratch0(), value); 4157 __ cvt_s_d(double_scratch0(), value);
4225 __ swc1(double_scratch0(), MemOperand(address, base_offset)); 4158 __ swc1(double_scratch0(), MemOperand(address, base_offset));
4226 } else { // Storing doubles, not floats. 4159 } else { // Storing doubles, not floats.
4227 __ sdc1(value, MemOperand(address, base_offset)); 4160 __ sdc1(value, MemOperand(address, base_offset));
4228 } 4161 }
4229 } else { 4162 } else {
4230 Register value(ToRegister(instr->value())); 4163 Register value(ToRegister(instr->value()));
4231 MemOperand mem_operand = PrepareKeyedOperand( 4164 MemOperand mem_operand = PrepareKeyedOperand(
4232 key, external_pointer, key_is_constant, constant_key, 4165 key, external_pointer, key_is_constant, constant_key,
4233 element_size_shift, shift_size, 4166 element_size_shift, shift_size,
4234 instr->additional_index(), additional_offset); 4167 instr->additional_index(), additional_offset);
4235 switch (elements_kind) { 4168 switch (elements_kind) {
4236 case EXTERNAL_PIXEL_ELEMENTS: 4169 case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
4237 case EXTERNAL_BYTE_ELEMENTS: 4170 case EXTERNAL_INT8_ELEMENTS:
4238 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4171 case EXTERNAL_UINT8_ELEMENTS:
4239 case UINT8_ELEMENTS: 4172 case UINT8_ELEMENTS:
4240 case UINT8_CLAMPED_ELEMENTS: 4173 case UINT8_CLAMPED_ELEMENTS:
4241 case INT8_ELEMENTS: 4174 case INT8_ELEMENTS:
4242 __ sb(value, mem_operand); 4175 __ sb(value, mem_operand);
4243 break; 4176 break;
4244 case EXTERNAL_SHORT_ELEMENTS: 4177 case EXTERNAL_INT16_ELEMENTS:
4245 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4178 case EXTERNAL_UINT16_ELEMENTS:
4246 case INT16_ELEMENTS: 4179 case INT16_ELEMENTS:
4247 case UINT16_ELEMENTS: 4180 case UINT16_ELEMENTS:
4248 __ sh(value, mem_operand); 4181 __ sh(value, mem_operand);
4249 break; 4182 break;
4250 case EXTERNAL_INT_ELEMENTS: 4183 case EXTERNAL_INT32_ELEMENTS:
4251 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4184 case EXTERNAL_UINT32_ELEMENTS:
4252 case INT32_ELEMENTS: 4185 case INT32_ELEMENTS:
4253 case UINT32_ELEMENTS: 4186 case UINT32_ELEMENTS:
4254 __ sw(value, mem_operand); 4187 __ sw(value, mem_operand);
4255 break; 4188 break;
4256 case FLOAT32_ELEMENTS: 4189 case FLOAT32_ELEMENTS:
4257 case FLOAT64_ELEMENTS: 4190 case FLOAT64_ELEMENTS:
4258 case EXTERNAL_FLOAT_ELEMENTS: 4191 case EXTERNAL_FLOAT32_ELEMENTS:
4259 case EXTERNAL_DOUBLE_ELEMENTS: 4192 case EXTERNAL_FLOAT64_ELEMENTS:
4260 case FAST_DOUBLE_ELEMENTS: 4193 case FAST_DOUBLE_ELEMENTS:
4261 case FAST_ELEMENTS: 4194 case FAST_ELEMENTS:
4262 case FAST_SMI_ELEMENTS: 4195 case FAST_SMI_ELEMENTS:
4263 case FAST_HOLEY_DOUBLE_ELEMENTS: 4196 case FAST_HOLEY_DOUBLE_ELEMENTS:
4264 case FAST_HOLEY_ELEMENTS: 4197 case FAST_HOLEY_ELEMENTS:
4265 case FAST_HOLEY_SMI_ELEMENTS: 4198 case FAST_HOLEY_SMI_ELEMENTS:
4266 case DICTIONARY_ELEMENTS: 4199 case DICTIONARY_ELEMENTS:
4267 case NON_STRICT_ARGUMENTS_ELEMENTS: 4200 case NON_STRICT_ARGUMENTS_ELEMENTS:
4268 UNREACHABLE(); 4201 UNREACHABLE();
4269 break; 4202 break;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4301 } 4234 }
4302 4235
4303 if (instr->NeedsCanonicalization()) { 4236 if (instr->NeedsCanonicalization()) {
4304 Label is_nan; 4237 Label is_nan;
4305 // Check for NaN. All NaNs must be canonicalized. 4238 // Check for NaN. All NaNs must be canonicalized.
4306 __ BranchF(NULL, &is_nan, eq, value, value); 4239 __ BranchF(NULL, &is_nan, eq, value, value);
4307 __ Branch(&not_nan); 4240 __ Branch(&not_nan);
4308 4241
4309 // Only load canonical NaN if the comparison above set the overflow. 4242 // Only load canonical NaN if the comparison above set the overflow.
4310 __ bind(&is_nan); 4243 __ bind(&is_nan);
4311 __ Move(double_scratch, 4244 __ LoadRoot(at, Heap::kNanValueRootIndex);
4312 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); 4245 __ ldc1(double_scratch, FieldMemOperand(at, HeapNumber::kValueOffset));
4313 __ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() << 4246 __ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() <<
4314 element_size_shift)); 4247 element_size_shift));
4315 __ Branch(&done); 4248 __ Branch(&done);
4316 } 4249 }
4317 4250
4318 __ bind(&not_nan); 4251 __ bind(&not_nan);
4319 __ sdc1(value, MemOperand(scratch, instr->additional_index() << 4252 __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
4320 element_size_shift)); 4253 element_size_shift));
4321 __ bind(&done); 4254 __ bind(&done);
4322 } 4255 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
4437 Label no_memento_found; 4370 Label no_memento_found;
4438 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found, 4371 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found,
4439 ne, &no_memento_found); 4372 ne, &no_memento_found);
4440 DeoptimizeIf(al, instr->environment()); 4373 DeoptimizeIf(al, instr->environment());
4441 __ bind(&no_memento_found); 4374 __ bind(&no_memento_found);
4442 } 4375 }
4443 4376
4444 4377
4445 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4378 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4446 ASSERT(ToRegister(instr->context()).is(cp)); 4379 ASSERT(ToRegister(instr->context()).is(cp));
4447 if (FLAG_new_string_add) { 4380 ASSERT(ToRegister(instr->left()).is(a1));
4448 ASSERT(ToRegister(instr->left()).is(a1)); 4381 ASSERT(ToRegister(instr->right()).is(a0));
4449 ASSERT(ToRegister(instr->right()).is(a0)); 4382 StringAddStub stub(instr->hydrogen()->flags(),
4450 NewStringAddStub stub(instr->hydrogen()->flags(), 4383 instr->hydrogen()->pretenure_flag());
4451 isolate()->heap()->GetPretenureMode()); 4384 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4452 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4453 } else {
4454 __ push(ToRegister(instr->left()));
4455 __ push(ToRegister(instr->right()));
4456 StringAddStub stub(instr->hydrogen()->flags());
4457 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4458 }
4459 } 4385 }
4460 4386
4461 4387
4462 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 4388 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4463 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { 4389 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode {
4464 public: 4390 public:
4465 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 4391 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4466 : LDeferredCode(codegen), instr_(instr) { } 4392 : LDeferredCode(codegen), instr_(instr) { }
4467 virtual void Generate() V8_OVERRIDE { 4393 virtual void Generate() V8_OVERRIDE {
4468 codegen()->DoDeferredStringCharCodeAt(instr_); 4394 codegen()->DoDeferredStringCharCodeAt(instr_);
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
4879 // Heap number map check. 4805 // Heap number map check.
4880 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4806 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4881 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 4807 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
4882 // This 'at' value and scratch1 map value are used for tests in both clauses 4808 // This 'at' value and scratch1 map value are used for tests in both clauses
4883 // of the if. 4809 // of the if.
4884 4810
4885 if (instr->truncating()) { 4811 if (instr->truncating()) {
4886 // Performs a truncating conversion of a floating point number as used by 4812 // Performs a truncating conversion of a floating point number as used by
4887 // the JS bitwise operations. 4813 // the JS bitwise operations.
4888 Label no_heap_number, check_bools, check_false; 4814 Label no_heap_number, check_bools, check_false;
4889 __ Branch(&no_heap_number, ne, scratch1, Operand(at)); // HeapNumber map? 4815 // Check HeapNumber map.
4890 __ mov(scratch2, input_reg); 4816 __ Branch(USE_DELAY_SLOT, &no_heap_number, ne, scratch1, Operand(at));
4817 __ mov(scratch2, input_reg); // In delay slot.
4891 __ TruncateHeapNumberToI(input_reg, scratch2); 4818 __ TruncateHeapNumberToI(input_reg, scratch2);
4892 __ Branch(&done); 4819 __ Branch(&done);
4893 4820
4894 // Check for Oddballs. Undefined/False is converted to zero and True to one 4821 // Check for Oddballs. Undefined/False is converted to zero and True to one
4895 // for truncating conversions. 4822 // for truncating conversions.
4896 __ bind(&no_heap_number); 4823 __ bind(&no_heap_number);
4897 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 4824 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
4898 __ Branch(&check_bools, ne, input_reg, Operand(at)); 4825 __ Branch(&check_bools, ne, input_reg, Operand(at));
4899 ASSERT(ToRegister(instr->result()).is(input_reg)); 4826 ASSERT(ToRegister(instr->result()).is(input_reg));
4900 __ Branch(USE_DELAY_SLOT, &done); 4827 __ Branch(USE_DELAY_SLOT, &done);
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
5281 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5208 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
5282 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5209 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5283 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5210 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5284 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); 5211 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
5285 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5212 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5286 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5213 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5287 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); 5214 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE);
5288 } 5215 }
5289 if (instr->size()->IsConstantOperand()) { 5216 if (instr->size()->IsConstantOperand()) {
5290 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5217 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5291 __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags); 5218 if (size <= Page::kMaxRegularHeapObjectSize) {
5219 __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
5220 } else {
5221 __ jmp(deferred->entry());
5222 }
5292 } else { 5223 } else {
5293 Register size = ToRegister(instr->size()); 5224 Register size = ToRegister(instr->size());
5294 __ Allocate(size, 5225 __ Allocate(size,
5295 result, 5226 result,
5296 scratch, 5227 scratch,
5297 scratch2, 5228 scratch2,
5298 deferred->entry(), 5229 deferred->entry(),
5299 flags); 5230 flags);
5300 } 5231 }
5301 5232
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
5822 __ Subu(scratch, result, scratch); 5753 __ Subu(scratch, result, scratch);
5823 __ lw(result, FieldMemOperand(scratch, 5754 __ lw(result, FieldMemOperand(scratch,
5824 FixedArray::kHeaderSize - kPointerSize)); 5755 FixedArray::kHeaderSize - kPointerSize));
5825 __ bind(&done); 5756 __ bind(&done);
5826 } 5757 }
5827 5758
5828 5759
5829 #undef __ 5760 #undef __
5830 5761
5831 } } // namespace v8::internal 5762 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips/ic-mips.cc ('k') | src/mips/lithium-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698