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

Side by Side Diff: src/x64/lithium-codegen-x64.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/x64/ic-x64.cc ('k') | src/x64/lithium-gap-resolver-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 GenerateDeferredCode() && 80 GenerateDeferredCode() &&
81 GenerateJumpTable() && 81 GenerateJumpTable() &&
82 GenerateSafepointTable(); 82 GenerateSafepointTable();
83 } 83 }
84 84
85 85
86 void LCodeGen::FinishCode(Handle<Code> code) { 86 void LCodeGen::FinishCode(Handle<Code> code) {
87 ASSERT(is_done()); 87 ASSERT(is_done());
88 code->set_stack_slots(GetStackSlotCount()); 88 code->set_stack_slots(GetStackSlotCount());
89 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 89 code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
90 RegisterDependentCodeForEmbeddedMaps(code); 90 if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
91 PopulateDeoptimizationData(code); 91 PopulateDeoptimizationData(code);
92 info()->CommitDependencies(code); 92 info()->CommitDependencies(code);
93 } 93 }
94 94
95 95
96 void LChunkBuilder::Abort(BailoutReason reason) { 96 void LChunkBuilder::Abort(BailoutReason reason) {
97 info()->set_bailout_reason(reason); 97 info()->set_bailout_reason(reason);
98 status_ = ABORTED; 98 status_ = ABORTED;
99 } 99 }
100 100
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 if (info()->saves_caller_doubles()) { 211 if (info()->saves_caller_doubles()) {
212 SaveCallerDoubles(); 212 SaveCallerDoubles();
213 } 213 }
214 } 214 }
215 215
216 // Possibly allocate a local context. 216 // Possibly allocate a local context.
217 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 217 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
218 if (heap_slots > 0) { 218 if (heap_slots > 0) {
219 Comment(";;; Allocate local context"); 219 Comment(";;; Allocate local context");
220 // Argument to NewContext is the function, which is still in rdi. 220 // Argument to NewContext is the function, which is still in rdi.
221 __ push(rdi);
222 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 221 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
223 FastNewContextStub stub(heap_slots); 222 FastNewContextStub stub(heap_slots);
224 __ CallStub(&stub); 223 __ CallStub(&stub);
225 } else { 224 } else {
225 __ push(rdi);
226 __ CallRuntime(Runtime::kNewFunctionContext, 1); 226 __ CallRuntime(Runtime::kNewFunctionContext, 1);
227 } 227 }
228 RecordSafepoint(Safepoint::kNoLazyDeopt); 228 RecordSafepoint(Safepoint::kNoLazyDeopt);
229 // Context is returned in both rax and rsi. It replaces the context 229 // Context is returned in rax. It replaces the context passed to us.
230 // passed to us. It's saved in the stack and kept live in rsi. 230 // It's saved in the stack and kept live in rsi.
231 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); 231 __ movp(rsi, rax);
232 __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rax);
232 233
233 // Copy any necessary parameters into the context. 234 // Copy any necessary parameters into the context.
234 int num_parameters = scope()->num_parameters(); 235 int num_parameters = scope()->num_parameters();
235 for (int i = 0; i < num_parameters; i++) { 236 for (int i = 0; i < num_parameters; i++) {
236 Variable* var = scope()->parameter(i); 237 Variable* var = scope()->parameter(i);
237 if (var->IsContextSlot()) { 238 if (var->IsContextSlot()) {
238 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 239 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
239 (num_parameters - 1 - i) * kPointerSize; 240 (num_parameters - 1 - i) * kPointerSize;
240 // Load parameter from stack. 241 // Load parameter from stack.
241 __ movp(rax, Operand(rbp, parameter_offset)); 242 __ movp(rax, Operand(rbp, parameter_offset));
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 321
321 322
322 bool LCodeGen::GenerateDeferredCode() { 323 bool LCodeGen::GenerateDeferredCode() {
323 ASSERT(is_generating()); 324 ASSERT(is_generating());
324 if (deferred_.length() > 0) { 325 if (deferred_.length() > 0) {
325 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 326 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
326 LDeferredCode* code = deferred_[i]; 327 LDeferredCode* code = deferred_[i];
327 328
328 HValue* value = 329 HValue* value =
329 instructions_->at(code->instruction_index())->hydrogen_value(); 330 instructions_->at(code->instruction_index())->hydrogen_value();
330 RecordAndWritePosition(value->position()); 331 RecordAndWritePosition(
332 chunk()->graph()->SourcePositionToScriptPosition(value->position()));
331 333
332 Comment(";;; <@%d,#%d> " 334 Comment(";;; <@%d,#%d> "
333 "-------------------- Deferred %s --------------------", 335 "-------------------- Deferred %s --------------------",
334 code->instruction_index(), 336 code->instruction_index(),
335 code->instr()->hydrogen_value()->id(), 337 code->instr()->hydrogen_value()->id(),
336 code->instr()->Mnemonic()); 338 code->instr()->Mnemonic());
337 __ bind(code->entry()); 339 __ bind(code->entry());
338 if (NeedsDeferredFrame()) { 340 if (NeedsDeferredFrame()) {
339 Comment(";;; Build frame"); 341 Comment(";;; Build frame");
340 ASSERT(!frame_is_built_); 342 ASSERT(!frame_is_built_);
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 785 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
784 int length = deoptimizations_.length(); 786 int length = deoptimizations_.length();
785 if (length == 0) return; 787 if (length == 0) return;
786 Handle<DeoptimizationInputData> data = 788 Handle<DeoptimizationInputData> data =
787 factory()->NewDeoptimizationInputData(length, TENURED); 789 factory()->NewDeoptimizationInputData(length, TENURED);
788 790
789 Handle<ByteArray> translations = 791 Handle<ByteArray> translations =
790 translations_.CreateByteArray(isolate()->factory()); 792 translations_.CreateByteArray(isolate()->factory());
791 data->SetTranslationByteArray(*translations); 793 data->SetTranslationByteArray(*translations);
792 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 794 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
795 data->SetOptimizationId(Smi::FromInt(info_->optimization_id()));
796 if (info_->IsOptimizing()) {
797 // Reference to shared function info does not change between phases.
798 AllowDeferredHandleDereference allow_handle_dereference;
799 data->SetSharedFunctionInfo(*info_->shared_info());
800 } else {
801 data->SetSharedFunctionInfo(Smi::FromInt(0));
802 }
793 803
794 Handle<FixedArray> literals = 804 Handle<FixedArray> literals =
795 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 805 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
796 { AllowDeferredHandleDereference copy_handles; 806 { AllowDeferredHandleDereference copy_handles;
797 for (int i = 0; i < deoptimization_literals_.length(); i++) { 807 for (int i = 0; i < deoptimization_literals_.length(); i++) {
798 literals->set(i, *deoptimization_literals_[i]); 808 literals->set(i, *deoptimization_literals_[i]);
799 } 809 }
800 data->SetLiteralArray(*literals); 810 data->SetLiteralArray(*literals);
801 } 811 }
802 812
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 954
945 void LCodeGen::DoParameter(LParameter* instr) { 955 void LCodeGen::DoParameter(LParameter* instr) {
946 // Nothing to do. 956 // Nothing to do.
947 } 957 }
948 958
949 959
950 void LCodeGen::DoCallStub(LCallStub* instr) { 960 void LCodeGen::DoCallStub(LCallStub* instr) {
951 ASSERT(ToRegister(instr->context()).is(rsi)); 961 ASSERT(ToRegister(instr->context()).is(rsi));
952 ASSERT(ToRegister(instr->result()).is(rax)); 962 ASSERT(ToRegister(instr->result()).is(rax));
953 switch (instr->hydrogen()->major_key()) { 963 switch (instr->hydrogen()->major_key()) {
954 case CodeStub::RegExpConstructResult: {
955 RegExpConstructResultStub stub;
956 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
957 break;
958 }
959 case CodeStub::RegExpExec: { 964 case CodeStub::RegExpExec: {
960 RegExpExecStub stub; 965 RegExpExecStub stub;
961 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 966 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
962 break; 967 break;
963 } 968 }
964 case CodeStub::SubString: { 969 case CodeStub::SubString: {
965 SubStringStub stub; 970 SubStringStub stub;
966 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 971 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
967 break; 972 break;
968 } 973 }
(...skipping 10 matching lines...) Expand all
979 984
980 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 985 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
981 GenerateOsrPrologue(); 986 GenerateOsrPrologue();
982 } 987 }
983 988
984 989
985 void LCodeGen::DoModI(LModI* instr) { 990 void LCodeGen::DoModI(LModI* instr) {
986 HMod* hmod = instr->hydrogen(); 991 HMod* hmod = instr->hydrogen();
987 HValue* left = hmod->left(); 992 HValue* left = hmod->left();
988 HValue* right = hmod->right(); 993 HValue* right = hmod->right();
989 if (hmod->HasPowerOf2Divisor()) { 994 if (hmod->RightIsPowerOf2()) {
990 // TODO(svenpanne) We should really do the strength reduction on the 995 // TODO(svenpanne) We should really do the strength reduction on the
991 // Hydrogen level. 996 // Hydrogen level.
992 Register left_reg = ToRegister(instr->left()); 997 Register left_reg = ToRegister(instr->left());
993 ASSERT(left_reg.is(ToRegister(instr->result()))); 998 ASSERT(left_reg.is(ToRegister(instr->result())));
994 999
995 // Note: The code below even works when right contains kMinInt. 1000 // Note: The code below even works when right contains kMinInt.
996 int32_t divisor = Abs(right->GetInteger32Constant()); 1001 int32_t divisor = Abs(right->GetInteger32Constant());
997 1002
998 Label left_is_not_negative, done; 1003 Label left_is_not_negative, done;
999 if (left->CanBeNegative()) { 1004 if (left->CanBeNegative()) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 // Result just fit in r64, because it's int32 * uint32. 1150 // Result just fit in r64, because it's int32 * uint32.
1146 __ imul(reg2, reg1); 1151 __ imul(reg2, reg1);
1147 1152
1148 __ addq(reg2, Immediate(1 << 30)); 1153 __ addq(reg2, Immediate(1 << 30));
1149 __ sar(reg2, Immediate(shift)); 1154 __ sar(reg2, Immediate(shift));
1150 } 1155 }
1151 } 1156 }
1152 1157
1153 1158
1154 void LCodeGen::DoDivI(LDivI* instr) { 1159 void LCodeGen::DoDivI(LDivI* instr) {
1155 if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) { 1160 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) {
1156 Register dividend = ToRegister(instr->left()); 1161 Register dividend = ToRegister(instr->left());
1157 int32_t divisor = 1162 HDiv* hdiv = instr->hydrogen();
1158 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 1163 int32_t divisor = hdiv->right()->GetInteger32Constant();
1159 int32_t test_value = 0; 1164 Register result = ToRegister(instr->result());
1160 int32_t power = 0; 1165 ASSERT(!result.is(dividend));
1161 1166
1162 if (divisor > 0) { 1167 // Check for (0 / -x) that will produce negative zero.
1163 test_value = divisor - 1; 1168 if (hdiv->left()->RangeCanInclude(0) && divisor < 0 &&
1164 power = WhichPowerOf2(divisor); 1169 hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1165 } else { 1170 __ testl(dividend, dividend);
1166 // Check for (0 / -x) that will produce negative zero. 1171 DeoptimizeIf(zero, instr->environment());
1167 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1168 __ testl(dividend, dividend);
1169 DeoptimizeIf(zero, instr->environment());
1170 }
1171 // Check for (kMinInt / -1).
1172 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1173 __ cmpl(dividend, Immediate(kMinInt));
1174 DeoptimizeIf(zero, instr->environment());
1175 }
1176 test_value = - divisor - 1;
1177 power = WhichPowerOf2(-divisor);
1178 } 1172 }
1179 1173 // Check for (kMinInt / -1).
1180 if (test_value != 0) { 1174 if (hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1 &&
1181 if (instr->hydrogen()->CheckFlag( 1175 hdiv->CheckFlag(HValue::kCanOverflow)) {
1182 HInstruction::kAllUsesTruncatingToInt32)) { 1176 __ cmpl(dividend, Immediate(kMinInt));
1183 Label done, negative; 1177 DeoptimizeIf(zero, instr->environment());
1184 __ cmpl(dividend, Immediate(0));
1185 __ j(less, &negative, Label::kNear);
1186 __ sarl(dividend, Immediate(power));
1187 if (divisor < 0) __ negl(dividend);
1188 __ jmp(&done, Label::kNear);
1189
1190 __ bind(&negative);
1191 __ negl(dividend);
1192 __ sarl(dividend, Immediate(power));
1193 if (divisor > 0) __ negl(dividend);
1194 __ bind(&done);
1195 return; // Don't fall through to "__ neg" below.
1196 } else {
1197 // Deoptimize if remainder is not 0.
1198 __ testl(dividend, Immediate(test_value));
1199 DeoptimizeIf(not_zero, instr->environment());
1200 __ sarl(dividend, Immediate(power));
1201 }
1202 } 1178 }
1203 1179 // Deoptimize if remainder will not be 0.
1204 if (divisor < 0) __ negl(dividend); 1180 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1205 1181 __ testl(dividend, Immediate(Abs(divisor) - 1));
1182 DeoptimizeIf(not_zero, instr->environment());
1183 }
1184 __ Move(result, dividend);
1185 int32_t shift = WhichPowerOf2(Abs(divisor));
1186 if (shift > 0) {
1187 // The arithmetic shift is always OK, the 'if' is an optimization only.
1188 if (shift > 1) __ sarl(result, Immediate(31));
1189 __ shrl(result, Immediate(32 - shift));
1190 __ addl(result, dividend);
1191 __ sarl(result, Immediate(shift));
1192 }
1193 if (divisor < 0) __ negl(result);
1206 return; 1194 return;
1207 } 1195 }
1208 1196
1209 LOperand* right = instr->right(); 1197 LOperand* right = instr->right();
1210 ASSERT(ToRegister(instr->result()).is(rax)); 1198 ASSERT(ToRegister(instr->result()).is(rax));
1211 ASSERT(ToRegister(instr->left()).is(rax)); 1199 ASSERT(ToRegister(instr->left()).is(rax));
1212 ASSERT(!ToRegister(instr->right()).is(rax)); 1200 ASSERT(!ToRegister(instr->right()).is(rax));
1213 ASSERT(!ToRegister(instr->right()).is(rdx)); 1201 ASSERT(!ToRegister(instr->right()).is(rdx));
1214 1202
1215 Register left_reg = rax; 1203 Register left_reg = rax;
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 } 1559 }
1572 1560
1573 1561
1574 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1562 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1575 Register result = ToRegister(instr->result()); 1563 Register result = ToRegister(instr->result());
1576 Register map = ToRegister(instr->value()); 1564 Register map = ToRegister(instr->value());
1577 __ EnumLength(result, map); 1565 __ EnumLength(result, map);
1578 } 1566 }
1579 1567
1580 1568
1581 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1582 Register result = ToRegister(instr->result());
1583 Register input = ToRegister(instr->value());
1584
1585 // Load map into |result|.
1586 __ movp(result, FieldOperand(input, HeapObject::kMapOffset));
1587 // Load the map's "bit field 2" into |result|. We only need the first byte.
1588 __ movzxbq(result, FieldOperand(result, Map::kBitField2Offset));
1589 // Retrieve elements_kind from bit field 2.
1590 __ and_(result, Immediate(Map::kElementsKindMask));
1591 __ shr(result, Immediate(Map::kElementsKindShift));
1592 }
1593
1594
1595 void LCodeGen::DoValueOf(LValueOf* instr) {
1596 Register input = ToRegister(instr->value());
1597 Register result = ToRegister(instr->result());
1598 ASSERT(input.is(result));
1599 Label done;
1600
1601 if (!instr->hydrogen()->value()->IsHeapObject()) {
1602 // If the object is a smi return the object.
1603 __ JumpIfSmi(input, &done, Label::kNear);
1604 }
1605
1606 // If the object is not a value type, return the object.
1607 __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister);
1608 __ j(not_equal, &done, Label::kNear);
1609 __ movp(result, FieldOperand(input, JSValue::kValueOffset));
1610
1611 __ bind(&done);
1612 }
1613
1614
1615 void LCodeGen::DoDateField(LDateField* instr) { 1569 void LCodeGen::DoDateField(LDateField* instr) {
1616 Register object = ToRegister(instr->date()); 1570 Register object = ToRegister(instr->date());
1617 Register result = ToRegister(instr->result()); 1571 Register result = ToRegister(instr->result());
1618 Smi* index = instr->index(); 1572 Smi* index = instr->index();
1619 Label runtime, done, not_date_object; 1573 Label runtime, done, not_date_object;
1620 ASSERT(object.is(result)); 1574 ASSERT(object.is(result));
1621 ASSERT(object.is(rax)); 1575 ASSERT(object.is(rax));
1622 1576
1623 Condition cc = masm()->CheckSmi(object); 1577 Condition cc = masm()->CheckSmi(object);
1624 DeoptimizeIf(cc, instr->environment()); 1578 DeoptimizeIf(cc, instr->environment());
(...skipping 10 matching lines...) Expand all
1635 __ cmpq(kScratchRegister, FieldOperand(object, 1589 __ cmpq(kScratchRegister, FieldOperand(object,
1636 JSDate::kCacheStampOffset)); 1590 JSDate::kCacheStampOffset));
1637 __ j(not_equal, &runtime, Label::kNear); 1591 __ j(not_equal, &runtime, Label::kNear);
1638 __ movp(result, FieldOperand(object, JSDate::kValueOffset + 1592 __ movp(result, FieldOperand(object, JSDate::kValueOffset +
1639 kPointerSize * index->value())); 1593 kPointerSize * index->value()));
1640 __ jmp(&done, Label::kNear); 1594 __ jmp(&done, Label::kNear);
1641 } 1595 }
1642 __ bind(&runtime); 1596 __ bind(&runtime);
1643 __ PrepareCallCFunction(2); 1597 __ PrepareCallCFunction(2);
1644 __ movp(arg_reg_1, object); 1598 __ movp(arg_reg_1, object);
1645 __ Move(arg_reg_2, index, RelocInfo::NONE64); 1599 __ Move(arg_reg_2, index, Assembler::RelocInfoNone());
1646 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 1600 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
1647 __ bind(&done); 1601 __ bind(&done);
1648 } 1602 }
1649 } 1603 }
1650 1604
1651 1605
1652 Operand LCodeGen::BuildSeqStringOperand(Register string, 1606 Operand LCodeGen::BuildSeqStringOperand(Register string,
1653 LOperand* index, 1607 LOperand* index,
1654 String::Encoding encoding) { 1608 String::Encoding encoding) {
1655 if (index->IsConstantOperand()) { 1609 if (index->IsConstantOperand()) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 Register value = ToRegister(instr->value()); 1679 Register value = ToRegister(instr->value());
1726 if (encoding == String::ONE_BYTE_ENCODING) { 1680 if (encoding == String::ONE_BYTE_ENCODING) {
1727 __ movb(operand, value); 1681 __ movb(operand, value);
1728 } else { 1682 } else {
1729 __ movw(operand, value); 1683 __ movw(operand, value);
1730 } 1684 }
1731 } 1685 }
1732 } 1686 }
1733 1687
1734 1688
1735 void LCodeGen::DoThrow(LThrow* instr) {
1736 __ push(ToRegister(instr->value()));
1737 ASSERT(ToRegister(instr->context()).is(rsi));
1738 CallRuntime(Runtime::kThrow, 1, instr);
1739
1740 if (FLAG_debug_code) {
1741 Comment("Unreachable code.");
1742 __ int3();
1743 }
1744 }
1745
1746
1747 void LCodeGen::DoAddI(LAddI* instr) { 1689 void LCodeGen::DoAddI(LAddI* instr) {
1748 LOperand* left = instr->left(); 1690 LOperand* left = instr->left();
1749 LOperand* right = instr->right(); 1691 LOperand* right = instr->right();
1750 1692
1751 Representation target_rep = instr->hydrogen()->representation(); 1693 Representation target_rep = instr->hydrogen()->representation();
1752 bool is_q = target_rep.IsSmi() || target_rep.IsExternal(); 1694 bool is_q = target_rep.IsSmi() || target_rep.IsExternal();
1753 1695
1754 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { 1696 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1755 if (right->IsConstantOperand()) { 1697 if (right->IsConstantOperand()) {
1756 int32_t offset = ToInteger32(LConstantOperand::cast(right)); 1698 int32_t offset = ToInteger32(LConstantOperand::cast(right));
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after
2807 ASSERT(result.is(rax)); 2749 ASSERT(result.is(rax));
2808 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object()))); 2750 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
2809 } else { 2751 } else {
2810 Register object = ToRegister(instr->object()); 2752 Register object = ToRegister(instr->object());
2811 __ Load(result, MemOperand(object, offset), access.representation()); 2753 __ Load(result, MemOperand(object, offset), access.representation());
2812 } 2754 }
2813 return; 2755 return;
2814 } 2756 }
2815 2757
2816 Register object = ToRegister(instr->object()); 2758 Register object = ToRegister(instr->object());
2817 if (FLAG_track_double_fields && 2759 if (instr->hydrogen()->representation().IsDouble()) {
2818 instr->hydrogen()->representation().IsDouble()) {
2819 XMMRegister result = ToDoubleRegister(instr->result()); 2760 XMMRegister result = ToDoubleRegister(instr->result());
2820 __ movsd(result, FieldOperand(object, offset)); 2761 __ movsd(result, FieldOperand(object, offset));
2821 return; 2762 return;
2822 } 2763 }
2823 2764
2824 Register result = ToRegister(instr->result()); 2765 Register result = ToRegister(instr->result());
2825 if (!access.IsInobject()) { 2766 if (!access.IsInobject()) {
2826 __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2767 __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset));
2827 object = result; 2768 object = result;
2828 } 2769 }
2829 2770
2830 Representation representation = access.representation(); 2771 Representation representation = access.representation();
2831 if (representation.IsSmi() && 2772 if (representation.IsSmi() &&
2832 instr->hydrogen()->representation().IsInteger32()) { 2773 instr->hydrogen()->representation().IsInteger32()) {
2774 #ifdef DEBUG
2775 Register scratch = kScratchRegister;
2776 __ Load(scratch, FieldOperand(object, offset), representation);
2777 __ AssertSmi(scratch);
2778 #endif
2779
2833 // Read int value directly from upper half of the smi. 2780 // Read int value directly from upper half of the smi.
2834 STATIC_ASSERT(kSmiTag == 0); 2781 STATIC_ASSERT(kSmiTag == 0);
2835 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); 2782 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
2836 offset += kPointerSize / 2; 2783 offset += kPointerSize / 2;
2837 representation = Representation::Integer32(); 2784 representation = Representation::Integer32();
2838 } 2785 }
2839 __ Load(result, FieldOperand(object, offset), representation); 2786 __ Load(result, FieldOperand(object, offset), representation);
2840 } 2787 }
2841 2788
2842 2789
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2891 __ bind(&done); 2838 __ bind(&done);
2892 } 2839 }
2893 2840
2894 2841
2895 void LCodeGen::DoLoadRoot(LLoadRoot* instr) { 2842 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
2896 Register result = ToRegister(instr->result()); 2843 Register result = ToRegister(instr->result());
2897 __ LoadRoot(result, instr->index()); 2844 __ LoadRoot(result, instr->index());
2898 } 2845 }
2899 2846
2900 2847
2901 void LCodeGen::DoLoadExternalArrayPointer(
2902 LLoadExternalArrayPointer* instr) {
2903 Register result = ToRegister(instr->result());
2904 Register input = ToRegister(instr->object());
2905 __ movp(result, FieldOperand(input,
2906 ExternalPixelArray::kExternalPointerOffset));
2907 }
2908
2909
2910 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2848 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2911 Register arguments = ToRegister(instr->arguments()); 2849 Register arguments = ToRegister(instr->arguments());
2912 Register result = ToRegister(instr->result()); 2850 Register result = ToRegister(instr->result());
2913 2851
2914 if (instr->length()->IsConstantOperand() && 2852 if (instr->length()->IsConstantOperand() &&
2915 instr->index()->IsConstantOperand()) { 2853 instr->index()->IsConstantOperand()) {
2916 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); 2854 int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2917 int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length())); 2855 int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length()));
2918 StackArgumentsAccessor args(arguments, const_length, 2856 StackArgumentsAccessor args(arguments, const_length,
2919 ARGUMENTS_DONT_CONTAIN_RECEIVER); 2857 ARGUMENTS_DONT_CONTAIN_RECEIVER);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2953 int base_offset = instr->is_fixed_typed_array() 2891 int base_offset = instr->is_fixed_typed_array()
2954 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 2892 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
2955 : 0; 2893 : 0;
2956 Operand operand(BuildFastArrayOperand( 2894 Operand operand(BuildFastArrayOperand(
2957 instr->elements(), 2895 instr->elements(),
2958 key, 2896 key,
2959 elements_kind, 2897 elements_kind,
2960 base_offset, 2898 base_offset,
2961 instr->additional_index())); 2899 instr->additional_index()));
2962 2900
2963 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 2901 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
2964 elements_kind == FLOAT32_ELEMENTS) { 2902 elements_kind == FLOAT32_ELEMENTS) {
2965 XMMRegister result(ToDoubleRegister(instr->result())); 2903 XMMRegister result(ToDoubleRegister(instr->result()));
2966 __ movss(result, operand); 2904 __ movss(result, operand);
2967 __ cvtss2sd(result, result); 2905 __ cvtss2sd(result, result);
2968 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS || 2906 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
2969 elements_kind == FLOAT64_ELEMENTS) { 2907 elements_kind == FLOAT64_ELEMENTS) {
2970 __ movsd(ToDoubleRegister(instr->result()), operand); 2908 __ movsd(ToDoubleRegister(instr->result()), operand);
2971 } else { 2909 } else {
2972 Register result(ToRegister(instr->result())); 2910 Register result(ToRegister(instr->result()));
2973 switch (elements_kind) { 2911 switch (elements_kind) {
2974 case EXTERNAL_BYTE_ELEMENTS: 2912 case EXTERNAL_INT8_ELEMENTS:
2975 case INT8_ELEMENTS: 2913 case INT8_ELEMENTS:
2976 __ movsxbq(result, operand); 2914 __ movsxbq(result, operand);
2977 break; 2915 break;
2978 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 2916 case EXTERNAL_UINT8_ELEMENTS:
2979 case EXTERNAL_PIXEL_ELEMENTS: 2917 case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
2980 case UINT8_ELEMENTS: 2918 case UINT8_ELEMENTS:
2981 case UINT8_CLAMPED_ELEMENTS: 2919 case UINT8_CLAMPED_ELEMENTS:
2982 __ movzxbq(result, operand); 2920 __ movzxbq(result, operand);
2983 break; 2921 break;
2984 case EXTERNAL_SHORT_ELEMENTS: 2922 case EXTERNAL_INT16_ELEMENTS:
2985 case INT16_ELEMENTS: 2923 case INT16_ELEMENTS:
2986 __ movsxwq(result, operand); 2924 __ movsxwq(result, operand);
2987 break; 2925 break;
2988 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 2926 case EXTERNAL_UINT16_ELEMENTS:
2989 case UINT16_ELEMENTS: 2927 case UINT16_ELEMENTS:
2990 __ movzxwq(result, operand); 2928 __ movzxwq(result, operand);
2991 break; 2929 break;
2992 case EXTERNAL_INT_ELEMENTS: 2930 case EXTERNAL_INT32_ELEMENTS:
2993 case INT32_ELEMENTS: 2931 case INT32_ELEMENTS:
2994 __ movsxlq(result, operand); 2932 __ movsxlq(result, operand);
2995 break; 2933 break;
2996 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2934 case EXTERNAL_UINT32_ELEMENTS:
2997 case UINT32_ELEMENTS: 2935 case UINT32_ELEMENTS:
2998 __ movl(result, operand); 2936 __ movl(result, operand);
2999 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 2937 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3000 __ testl(result, result); 2938 __ testl(result, result);
3001 DeoptimizeIf(negative, instr->environment()); 2939 DeoptimizeIf(negative, instr->environment());
3002 } 2940 }
3003 break; 2941 break;
3004 case EXTERNAL_FLOAT_ELEMENTS: 2942 case EXTERNAL_FLOAT32_ELEMENTS:
3005 case EXTERNAL_DOUBLE_ELEMENTS: 2943 case EXTERNAL_FLOAT64_ELEMENTS:
3006 case FLOAT32_ELEMENTS: 2944 case FLOAT32_ELEMENTS:
3007 case FLOAT64_ELEMENTS: 2945 case FLOAT64_ELEMENTS:
3008 case FAST_ELEMENTS: 2946 case FAST_ELEMENTS:
3009 case FAST_SMI_ELEMENTS: 2947 case FAST_SMI_ELEMENTS:
3010 case FAST_DOUBLE_ELEMENTS: 2948 case FAST_DOUBLE_ELEMENTS:
3011 case FAST_HOLEY_ELEMENTS: 2949 case FAST_HOLEY_ELEMENTS:
3012 case FAST_HOLEY_SMI_ELEMENTS: 2950 case FAST_HOLEY_SMI_ELEMENTS:
3013 case FAST_HOLEY_DOUBLE_ELEMENTS: 2951 case FAST_HOLEY_DOUBLE_ELEMENTS:
3014 case DICTIONARY_ELEMENTS: 2952 case DICTIONARY_ELEMENTS:
3015 case NON_STRICT_ARGUMENTS_ELEMENTS: 2953 case NON_STRICT_ARGUMENTS_ELEMENTS:
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3077 } 3015 }
3078 } 3016 }
3079 3017
3080 bool requires_hole_check = hinstr->RequiresHoleCheck(); 3018 bool requires_hole_check = hinstr->RequiresHoleCheck();
3081 int offset = FixedArray::kHeaderSize - kHeapObjectTag; 3019 int offset = FixedArray::kHeaderSize - kHeapObjectTag;
3082 Representation representation = hinstr->representation(); 3020 Representation representation = hinstr->representation();
3083 3021
3084 if (representation.IsInteger32() && 3022 if (representation.IsInteger32() &&
3085 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { 3023 hinstr->elements_kind() == FAST_SMI_ELEMENTS) {
3086 ASSERT(!requires_hole_check); 3024 ASSERT(!requires_hole_check);
3025 #ifdef DEBUG
3026 Register scratch = kScratchRegister;
3027 __ Load(scratch,
3028 BuildFastArrayOperand(instr->elements(),
3029 key,
3030 FAST_ELEMENTS,
3031 offset,
3032 instr->additional_index()),
3033 Representation::Smi());
3034 __ AssertSmi(scratch);
3035 #endif
3087 // Read int value directly from upper half of the smi. 3036 // Read int value directly from upper half of the smi.
3088 STATIC_ASSERT(kSmiTag == 0); 3037 STATIC_ASSERT(kSmiTag == 0);
3089 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); 3038 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
3090 offset += kPointerSize / 2; 3039 offset += kPointerSize / 2;
3091 } 3040 }
3092 3041
3093 __ Load(result, 3042 __ Load(result,
3094 BuildFastArrayOperand(instr->elements(), 3043 BuildFastArrayOperand(instr->elements(),
3095 key, 3044 key,
3096 FAST_ELEMENTS, 3045 FAST_ELEMENTS,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
3214 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 3163 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3215 Register receiver = ToRegister(instr->receiver()); 3164 Register receiver = ToRegister(instr->receiver());
3216 Register function = ToRegister(instr->function()); 3165 Register function = ToRegister(instr->function());
3217 3166
3218 // If the receiver is null or undefined, we have to pass the global 3167 // If the receiver is null or undefined, we have to pass the global
3219 // object as a receiver to normal functions. Values have to be 3168 // object as a receiver to normal functions. Values have to be
3220 // passed unchanged to builtins and strict-mode functions. 3169 // passed unchanged to builtins and strict-mode functions.
3221 Label global_object, receiver_ok; 3170 Label global_object, receiver_ok;
3222 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3171 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
3223 3172
3224 // Do not transform the receiver to object for strict mode 3173 if (!instr->hydrogen()->known_function()) {
3225 // functions. 3174 // Do not transform the receiver to object for strict mode
3226 __ movp(kScratchRegister, 3175 // functions.
3227 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3176 __ movp(kScratchRegister,
3228 __ testb(FieldOperand(kScratchRegister, 3177 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
3229 SharedFunctionInfo::kStrictModeByteOffset), 3178 __ testb(FieldOperand(kScratchRegister,
3230 Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte)); 3179 SharedFunctionInfo::kStrictModeByteOffset),
3231 __ j(not_equal, &receiver_ok, dist); 3180 Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
3181 __ j(not_equal, &receiver_ok, dist);
3232 3182
3233 // Do not transform the receiver to object for builtins. 3183 // Do not transform the receiver to object for builtins.
3234 __ testb(FieldOperand(kScratchRegister, 3184 __ testb(FieldOperand(kScratchRegister,
3235 SharedFunctionInfo::kNativeByteOffset), 3185 SharedFunctionInfo::kNativeByteOffset),
3236 Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte)); 3186 Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
3237 __ j(not_equal, &receiver_ok, dist); 3187 __ j(not_equal, &receiver_ok, dist);
3188 }
3238 3189
3239 // Normal function. Replace undefined or null with global receiver. 3190 // Normal function. Replace undefined or null with global receiver.
3240 __ CompareRoot(receiver, Heap::kNullValueRootIndex); 3191 __ CompareRoot(receiver, Heap::kNullValueRootIndex);
3241 __ j(equal, &global_object, Label::kNear); 3192 __ j(equal, &global_object, Label::kNear);
3242 __ CompareRoot(receiver, Heap::kUndefinedValueRootIndex); 3193 __ CompareRoot(receiver, Heap::kUndefinedValueRootIndex);
3243 __ j(equal, &global_object, Label::kNear); 3194 __ j(equal, &global_object, Label::kNear);
3244 3195
3245 // The receiver should be a JS object. 3196 // The receiver should be a JS object.
3246 Condition is_smi = __ CheckSmi(receiver); 3197 Condition is_smi = __ CheckSmi(receiver);
3247 DeoptimizeIf(is_smi, instr->environment()); 3198 DeoptimizeIf(is_smi, instr->environment());
3248 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister); 3199 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister);
3249 DeoptimizeIf(below, instr->environment()); 3200 DeoptimizeIf(below, instr->environment());
3201
3250 __ jmp(&receiver_ok, Label::kNear); 3202 __ jmp(&receiver_ok, Label::kNear);
3251
3252 __ bind(&global_object); 3203 __ bind(&global_object);
3253 __ movp(receiver, FieldOperand(function, JSFunction::kContextOffset)); 3204 __ movp(receiver, FieldOperand(function, JSFunction::kContextOffset));
3254 __ movp(receiver, 3205 __ movp(receiver,
3255 Operand(receiver, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 3206 Operand(receiver,
3207 Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
3256 __ movp(receiver, 3208 __ movp(receiver,
3257 FieldOperand(receiver, GlobalObject::kGlobalReceiverOffset)); 3209 FieldOperand(receiver, GlobalObject::kGlobalReceiverOffset));
3210
3258 __ bind(&receiver_ok); 3211 __ bind(&receiver_ok);
3259 } 3212 }
3260 3213
3261 3214
3262 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3215 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3263 Register receiver = ToRegister(instr->receiver()); 3216 Register receiver = ToRegister(instr->receiver());
3264 Register function = ToRegister(instr->function()); 3217 Register function = ToRegister(instr->function());
3265 Register length = ToRegister(instr->length()); 3218 Register length = ToRegister(instr->length());
3266 Register elements = ToRegister(instr->elements()); 3219 Register elements = ToRegister(instr->elements());
3267 ASSERT(receiver.is(rax)); // Used for parameter count. 3220 ASSERT(receiver.is(rax)); // Used for parameter count.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3322 Register result = ToRegister(instr->result()); 3275 Register result = ToRegister(instr->result());
3323 if (info()->IsOptimizing()) { 3276 if (info()->IsOptimizing()) {
3324 __ movp(result, Operand(rbp, StandardFrameConstants::kContextOffset)); 3277 __ movp(result, Operand(rbp, StandardFrameConstants::kContextOffset));
3325 } else { 3278 } else {
3326 // If there is no frame, the context must be in rsi. 3279 // If there is no frame, the context must be in rsi.
3327 ASSERT(result.is(rsi)); 3280 ASSERT(result.is(rsi));
3328 } 3281 }
3329 } 3282 }
3330 3283
3331 3284
3332 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3333 Register context = ToRegister(instr->context());
3334 Register result = ToRegister(instr->result());
3335 __ movp(result,
3336 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3337 }
3338
3339
3340 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3285 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3341 ASSERT(ToRegister(instr->context()).is(rsi)); 3286 ASSERT(ToRegister(instr->context()).is(rsi));
3342 __ push(rsi); // The context is the first argument. 3287 __ push(rsi); // The context is the first argument.
3343 __ Push(instr->hydrogen()->pairs()); 3288 __ Push(instr->hydrogen()->pairs());
3344 __ Push(Smi::FromInt(instr->hydrogen()->flags())); 3289 __ Push(Smi::FromInt(instr->hydrogen()->flags()));
3345 CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3290 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3346 } 3291 }
3347 3292
3348 3293
3349 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3350 Register context = ToRegister(instr->context());
3351 Register result = ToRegister(instr->result());
3352 __ movp(result,
3353 Operand(context, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
3354 }
3355
3356
3357 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3358 Register global = ToRegister(instr->global());
3359 Register result = ToRegister(instr->result());
3360 __ movp(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset));
3361 }
3362
3363
3364 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 3294 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
3365 int formal_parameter_count, 3295 int formal_parameter_count,
3366 int arity, 3296 int arity,
3367 LInstruction* instr, 3297 LInstruction* instr,
3368 RDIState rdi_state) { 3298 RDIState rdi_state) {
3369 bool dont_adapt_arguments = 3299 bool dont_adapt_arguments =
3370 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 3300 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3371 bool can_invoke_directly = 3301 bool can_invoke_directly =
3372 dont_adapt_arguments || formal_parameter_count == arity; 3302 dont_adapt_arguments || formal_parameter_count == arity;
3373 3303
(...skipping 10 matching lines...) Expand all
3384 // Set rax to arguments count if adaption is not needed. Assumes that rax 3314 // Set rax to arguments count if adaption is not needed. Assumes that rax
3385 // is available to write to at this point. 3315 // is available to write to at this point.
3386 if (dont_adapt_arguments) { 3316 if (dont_adapt_arguments) {
3387 __ Set(rax, arity); 3317 __ Set(rax, arity);
3388 } 3318 }
3389 3319
3390 // Invoke function. 3320 // Invoke function.
3391 if (function.is_identical_to(info()->closure())) { 3321 if (function.is_identical_to(info()->closure())) {
3392 __ CallSelf(); 3322 __ CallSelf();
3393 } else { 3323 } else {
3394 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 3324 __ Call(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
3395 } 3325 }
3396 3326
3397 // Set up deoptimization. 3327 // Set up deoptimization.
3398 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); 3328 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
3399 } else { 3329 } else {
3400 // We need to adapt arguments. 3330 // We need to adapt arguments.
3401 SafepointGenerator generator( 3331 SafepointGenerator generator(
3402 this, pointers, Safepoint::kLazyDeopt); 3332 this, pointers, Safepoint::kLazyDeopt);
3403 ParameterCount count(arity); 3333 ParameterCount count(arity);
3404 ParameterCount expected(formal_parameter_count); 3334 ParameterCount expected(formal_parameter_count);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3449 HConstant* fun_const = HConstant::cast(instr->hydrogen()->function()); 3379 HConstant* fun_const = HConstant::cast(instr->hydrogen()->function());
3450 jsfun = Handle<JSFunction>::cast(fun_const->handle(isolate())); 3380 jsfun = Handle<JSFunction>::cast(fun_const->handle(isolate()));
3451 is_self_call = jsfun.is_identical_to(info()->closure()); 3381 is_self_call = jsfun.is_identical_to(info()->closure());
3452 } 3382 }
3453 3383
3454 if (is_self_call) { 3384 if (is_self_call) {
3455 __ CallSelf(); 3385 __ CallSelf();
3456 } else { 3386 } else {
3457 Operand target = FieldOperand(rdi, JSFunction::kCodeEntryOffset); 3387 Operand target = FieldOperand(rdi, JSFunction::kCodeEntryOffset);
3458 generator.BeforeCall(__ CallSize(target)); 3388 generator.BeforeCall(__ CallSize(target));
3459 __ call(target); 3389 __ Call(target);
3460 } 3390 }
3461 generator.AfterCall(); 3391 generator.AfterCall();
3462 } 3392 }
3463 3393
3464 3394
3465 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3395 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3466 Register input_reg = ToRegister(instr->value()); 3396 Register input_reg = ToRegister(instr->value());
3467 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 3397 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
3468 Heap::kHeapNumberMapRootIndex); 3398 Heap::kHeapNumberMapRootIndex);
3469 DeoptimizeIf(not_equal, instr->environment()); 3399 DeoptimizeIf(not_equal, instr->environment());
(...skipping 19 matching lines...) Expand all
3489 // Slow case: Call the runtime system to do the number allocation. 3419 // Slow case: Call the runtime system to do the number allocation.
3490 __ bind(&slow); 3420 __ bind(&slow);
3491 CallRuntimeFromDeferred( 3421 CallRuntimeFromDeferred(
3492 Runtime::kAllocateHeapNumber, 0, instr, instr->context()); 3422 Runtime::kAllocateHeapNumber, 0, instr, instr->context());
3493 // Set the pointer to the new heap number in tmp. 3423 // Set the pointer to the new heap number in tmp.
3494 if (!tmp.is(rax)) __ movp(tmp, rax); 3424 if (!tmp.is(rax)) __ movp(tmp, rax);
3495 // Restore input_reg after call to runtime. 3425 // Restore input_reg after call to runtime.
3496 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); 3426 __ LoadFromSafepointRegisterSlot(input_reg, input_reg);
3497 3427
3498 __ bind(&allocated); 3428 __ bind(&allocated);
3499 __ MoveDouble(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3429 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
3500 __ shl(tmp2, Immediate(1)); 3430 __ shl(tmp2, Immediate(1));
3501 __ shr(tmp2, Immediate(1)); 3431 __ shr(tmp2, Immediate(1));
3502 __ MoveDouble(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); 3432 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
3503 __ StoreToSafepointRegisterSlot(input_reg, tmp); 3433 __ StoreToSafepointRegisterSlot(input_reg, tmp);
3504 3434
3505 __ bind(&done); 3435 __ bind(&done);
3506 } 3436 }
3507 3437
3508 3438
3509 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 3439 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3510 Register input_reg = ToRegister(instr->value()); 3440 Register input_reg = ToRegister(instr->value());
3511 __ testl(input_reg, input_reg); 3441 __ testl(input_reg, input_reg);
3512 Label is_positive; 3442 Label is_positive;
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
3799 __ movsd(Operand(rsp, 0), input_reg); 3729 __ movsd(Operand(rsp, 0), input_reg);
3800 __ fld_d(Operand(rsp, 0)); 3730 __ fld_d(Operand(rsp, 0));
3801 __ fyl2x(); 3731 __ fyl2x();
3802 __ fstp_d(Operand(rsp, 0)); 3732 __ fstp_d(Operand(rsp, 0));
3803 __ movsd(input_reg, Operand(rsp, 0)); 3733 __ movsd(input_reg, Operand(rsp, 0));
3804 __ addq(rsp, Immediate(kDoubleSize)); 3734 __ addq(rsp, Immediate(kDoubleSize));
3805 __ bind(&done); 3735 __ bind(&done);
3806 } 3736 }
3807 3737
3808 3738
3739 void LCodeGen::DoMathClz32(LMathClz32* instr) {
3740 Register input = ToRegister(instr->value());
3741 Register result = ToRegister(instr->result());
3742 Label not_zero_input;
3743 __ bsrl(result, input);
3744
3745 __ j(not_zero, &not_zero_input);
3746 __ Set(result, 63); // 63^31 == 32
3747
3748 __ bind(&not_zero_input);
3749 __ xorl(result, Immediate(31)); // for x in [0..31], 31^x == 31-x.
3750 }
3751
3752
3809 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3753 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3810 ASSERT(ToRegister(instr->context()).is(rsi)); 3754 ASSERT(ToRegister(instr->context()).is(rsi));
3811 ASSERT(ToRegister(instr->function()).is(rdi)); 3755 ASSERT(ToRegister(instr->function()).is(rdi));
3812 ASSERT(instr->HasPointerMap()); 3756 ASSERT(instr->HasPointerMap());
3813 3757
3814 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 3758 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3815 if (known_function.is_null()) { 3759 if (known_function.is_null()) {
3816 LPointerMap* pointers = instr->pointer_map(); 3760 LPointerMap* pointers = instr->pointer_map();
3817 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3761 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3818 ParameterCount count(instr->arity()); 3762 ParameterCount count(instr->arity());
3819 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator); 3763 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator);
3820 } else { 3764 } else {
3821 CallKnownFunction(known_function, 3765 CallKnownFunction(known_function,
3822 instr->hydrogen()->formal_parameter_count(), 3766 instr->hydrogen()->formal_parameter_count(),
3823 instr->arity(), 3767 instr->arity(),
3824 instr, 3768 instr,
3825 RDI_CONTAINS_TARGET); 3769 RDI_CONTAINS_TARGET);
3826 } 3770 }
3827 } 3771 }
3828 3772
3829 3773
3830 void LCodeGen::DoCallFunction(LCallFunction* instr) { 3774 void LCodeGen::DoCallFunction(LCallFunction* instr) {
3831 ASSERT(ToRegister(instr->context()).is(rsi)); 3775 ASSERT(ToRegister(instr->context()).is(rsi));
3832 ASSERT(ToRegister(instr->function()).is(rdi)); 3776 ASSERT(ToRegister(instr->function()).is(rdi));
3833 ASSERT(ToRegister(instr->result()).is(rax)); 3777 ASSERT(ToRegister(instr->result()).is(rax));
3834 3778
3835 int arity = instr->arity(); 3779 int arity = instr->arity();
3836 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 3780 CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
3837 if (instr->hydrogen()->IsTailCall()) { 3781 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3838 if (NeedsEagerFrame()) __ leave();
3839 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
3840 } else {
3841 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3842 }
3843 } 3782 }
3844 3783
3845 3784
3846 void LCodeGen::DoCallNew(LCallNew* instr) { 3785 void LCodeGen::DoCallNew(LCallNew* instr) {
3847 ASSERT(ToRegister(instr->context()).is(rsi)); 3786 ASSERT(ToRegister(instr->context()).is(rsi));
3848 ASSERT(ToRegister(instr->constructor()).is(rdi)); 3787 ASSERT(ToRegister(instr->constructor()).is(rdi));
3849 ASSERT(ToRegister(instr->result()).is(rax)); 3788 ASSERT(ToRegister(instr->result()).is(rax));
3850 3789
3851 __ Set(rax, instr->arity()); 3790 __ Set(rax, instr->arity());
3852 // No cell in ebx for construct type feedback in optimized code 3791 // No cell in ebx for construct type feedback in optimized code
3853 Handle<Object> undefined_value(isolate()->factory()->undefined_value()); 3792 Handle<Object> undefined_value(isolate()->factory()->undefined_value());
3854 __ Move(rbx, undefined_value); 3793 __ Move(rbx, undefined_value);
3855 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 3794 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
3856 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 3795 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3857 } 3796 }
3858 3797
3859 3798
3860 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { 3799 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
3861 ASSERT(ToRegister(instr->context()).is(rsi)); 3800 ASSERT(ToRegister(instr->context()).is(rsi));
3862 ASSERT(ToRegister(instr->constructor()).is(rdi)); 3801 ASSERT(ToRegister(instr->constructor()).is(rdi));
3863 ASSERT(ToRegister(instr->result()).is(rax)); 3802 ASSERT(ToRegister(instr->result()).is(rax));
3864 3803
3865 __ Set(rax, instr->arity()); 3804 __ Set(rax, instr->arity());
3866 __ Move(rbx, instr->hydrogen()->property_cell()); 3805 __ Move(rbx, factory()->undefined_value());
3867 ElementsKind kind = instr->hydrogen()->elements_kind(); 3806 ElementsKind kind = instr->hydrogen()->elements_kind();
3868 AllocationSiteOverrideMode override_mode = 3807 AllocationSiteOverrideMode override_mode =
3869 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 3808 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
3870 ? DISABLE_ALLOCATION_SITES 3809 ? DISABLE_ALLOCATION_SITES
3871 : DONT_OVERRIDE; 3810 : DONT_OVERRIDE;
3872 3811
3873 if (instr->arity() == 0) { 3812 if (instr->arity() == 0) {
3874 ArrayNoArgumentConstructorStub stub(kind, override_mode); 3813 ArrayNoArgumentConstructorStub stub(kind, override_mode);
3875 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 3814 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3876 } else if (instr->arity() == 1) { 3815 } else if (instr->arity() == 1) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3932 Representation representation = instr->representation(); 3871 Representation representation = instr->representation();
3933 3872
3934 HObjectAccess access = hinstr->access(); 3873 HObjectAccess access = hinstr->access();
3935 int offset = access.offset(); 3874 int offset = access.offset();
3936 3875
3937 if (access.IsExternalMemory()) { 3876 if (access.IsExternalMemory()) {
3938 ASSERT(!hinstr->NeedsWriteBarrier()); 3877 ASSERT(!hinstr->NeedsWriteBarrier());
3939 Register value = ToRegister(instr->value()); 3878 Register value = ToRegister(instr->value());
3940 if (instr->object()->IsConstantOperand()) { 3879 if (instr->object()->IsConstantOperand()) {
3941 ASSERT(value.is(rax)); 3880 ASSERT(value.is(rax));
3942 ASSERT(!access.representation().IsSpecialization());
3943 LConstantOperand* object = LConstantOperand::cast(instr->object()); 3881 LConstantOperand* object = LConstantOperand::cast(instr->object());
3944 __ store_rax(ToExternalReference(object)); 3882 __ store_rax(ToExternalReference(object));
3945 } else { 3883 } else {
3946 Register object = ToRegister(instr->object()); 3884 Register object = ToRegister(instr->object());
3947 __ Store(MemOperand(object, offset), value, representation); 3885 __ Store(MemOperand(object, offset), value, representation);
3948 } 3886 }
3949 return; 3887 return;
3950 } 3888 }
3951 3889
3952 Register object = ToRegister(instr->object()); 3890 Register object = ToRegister(instr->object());
3953 Handle<Map> transition = instr->transition(); 3891 Handle<Map> transition = instr->transition();
3892 SmiCheck check_needed = hinstr->value()->IsHeapObject()
3893 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3954 3894
3955 if (FLAG_track_fields && representation.IsSmi()) { 3895 if (FLAG_track_fields && representation.IsSmi()) {
3956 if (instr->value()->IsConstantOperand()) { 3896 if (instr->value()->IsConstantOperand()) {
3957 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 3897 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3958 if (!IsInteger32Constant(operand_value) && 3898 if (!IsInteger32Constant(operand_value) &&
3959 !IsSmiConstant(operand_value)) { 3899 !IsSmiConstant(operand_value)) {
3960 DeoptimizeIf(no_condition, instr->environment()); 3900 DeoptimizeIf(no_condition, instr->environment());
3961 } 3901 }
3962 } 3902 }
3963 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 3903 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
3964 if (instr->value()->IsConstantOperand()) { 3904 if (instr->value()->IsConstantOperand()) {
3965 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 3905 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3966 if (IsInteger32Constant(operand_value)) { 3906 if (IsInteger32Constant(operand_value)) {
3967 DeoptimizeIf(no_condition, instr->environment()); 3907 DeoptimizeIf(no_condition, instr->environment());
3968 } 3908 }
3969 } else { 3909 } else {
3970 if (!hinstr->value()->type().IsHeapObject()) { 3910 if (!hinstr->value()->type().IsHeapObject()) {
3971 Register value = ToRegister(instr->value()); 3911 Register value = ToRegister(instr->value());
3972 Condition cc = masm()->CheckSmi(value); 3912 Condition cc = masm()->CheckSmi(value);
3973 DeoptimizeIf(cc, instr->environment()); 3913 DeoptimizeIf(cc, instr->environment());
3914
3915 // We know that value is a smi now, so we can omit the check below.
3916 check_needed = OMIT_SMI_CHECK;
3974 } 3917 }
3975 } 3918 }
3976 } else if (FLAG_track_double_fields && representation.IsDouble()) { 3919 } else if (representation.IsDouble()) {
3977 ASSERT(transition.is_null()); 3920 ASSERT(transition.is_null());
3978 ASSERT(access.IsInobject()); 3921 ASSERT(access.IsInobject());
3979 ASSERT(!hinstr->NeedsWriteBarrier()); 3922 ASSERT(!hinstr->NeedsWriteBarrier());
3980 XMMRegister value = ToDoubleRegister(instr->value()); 3923 XMMRegister value = ToDoubleRegister(instr->value());
3981 __ movsd(FieldOperand(object, offset), value); 3924 __ movsd(FieldOperand(object, offset), value);
3982 return; 3925 return;
3983 } 3926 }
3984 3927
3985 if (!transition.is_null()) { 3928 if (!transition.is_null()) {
3986 if (!hinstr->NeedsWriteBarrierForMap()) { 3929 if (!hinstr->NeedsWriteBarrierForMap()) {
3987 __ Move(FieldOperand(object, HeapObject::kMapOffset), transition); 3930 __ Move(FieldOperand(object, HeapObject::kMapOffset), transition);
3988 } else { 3931 } else {
3989 Register temp = ToRegister(instr->temp()); 3932 Register temp = ToRegister(instr->temp());
3990 __ Move(kScratchRegister, transition); 3933 __ Move(kScratchRegister, transition);
3991 __ movp(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); 3934 __ movp(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister);
3992 // Update the write barrier for the map field. 3935 // Update the write barrier for the map field.
3993 __ RecordWriteField(object, 3936 __ RecordWriteField(object,
3994 HeapObject::kMapOffset, 3937 HeapObject::kMapOffset,
3995 kScratchRegister, 3938 kScratchRegister,
3996 temp, 3939 temp,
3997 kSaveFPRegs, 3940 kSaveFPRegs,
3998 OMIT_REMEMBERED_SET, 3941 OMIT_REMEMBERED_SET,
3999 OMIT_SMI_CHECK); 3942 OMIT_SMI_CHECK);
4000 } 3943 }
4001 } 3944 }
4002 3945
4003 // Do the store. 3946 // Do the store.
4004 SmiCheck check_needed = hinstr->value()->IsHeapObject()
4005 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4006
4007 Register write_register = object; 3947 Register write_register = object;
4008 if (!access.IsInobject()) { 3948 if (!access.IsInobject()) {
4009 write_register = ToRegister(instr->temp()); 3949 write_register = ToRegister(instr->temp());
4010 __ movp(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); 3950 __ movp(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
4011 } 3951 }
4012 3952
4013 if (representation.IsSmi() && 3953 if (representation.IsSmi() &&
4014 hinstr->value()->representation().IsInteger32()) { 3954 hinstr->value()->representation().IsInteger32()) {
4015 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); 3955 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
3956 #ifdef DEBUG
3957 Register scratch = kScratchRegister;
3958 __ Load(scratch, FieldOperand(write_register, offset), representation);
3959 __ AssertSmi(scratch);
3960 #endif
4016 // Store int value directly to upper half of the smi. 3961 // Store int value directly to upper half of the smi.
4017 STATIC_ASSERT(kSmiTag == 0); 3962 STATIC_ASSERT(kSmiTag == 0);
4018 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); 3963 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
4019 offset += kPointerSize / 2; 3964 offset += kPointerSize / 2;
4020 representation = Representation::Integer32(); 3965 representation = Representation::Integer32();
4021 } 3966 }
4022 3967
4023 Operand operand = FieldOperand(write_register, offset); 3968 Operand operand = FieldOperand(write_register, offset);
4024 3969
4025 if (instr->value()->IsRegister()) { 3970 if (instr->value()->IsRegister()) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
4145 int base_offset = instr->is_fixed_typed_array() 4090 int base_offset = instr->is_fixed_typed_array()
4146 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 4091 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
4147 : 0; 4092 : 0;
4148 Operand operand(BuildFastArrayOperand( 4093 Operand operand(BuildFastArrayOperand(
4149 instr->elements(), 4094 instr->elements(),
4150 key, 4095 key,
4151 elements_kind, 4096 elements_kind,
4152 base_offset, 4097 base_offset,
4153 instr->additional_index())); 4098 instr->additional_index()));
4154 4099
4155 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4100 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
4156 elements_kind == FLOAT32_ELEMENTS) { 4101 elements_kind == FLOAT32_ELEMENTS) {
4157 XMMRegister value(ToDoubleRegister(instr->value())); 4102 XMMRegister value(ToDoubleRegister(instr->value()));
4158 __ cvtsd2ss(value, value); 4103 __ cvtsd2ss(value, value);
4159 __ movss(operand, value); 4104 __ movss(operand, value);
4160 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS || 4105 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
4161 elements_kind == FLOAT64_ELEMENTS) { 4106 elements_kind == FLOAT64_ELEMENTS) {
4162 __ movsd(operand, ToDoubleRegister(instr->value())); 4107 __ movsd(operand, ToDoubleRegister(instr->value()));
4163 } else { 4108 } else {
4164 Register value(ToRegister(instr->value())); 4109 Register value(ToRegister(instr->value()));
4165 switch (elements_kind) { 4110 switch (elements_kind) {
4166 case EXTERNAL_PIXEL_ELEMENTS: 4111 case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
4167 case EXTERNAL_BYTE_ELEMENTS: 4112 case EXTERNAL_INT8_ELEMENTS:
4168 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4113 case EXTERNAL_UINT8_ELEMENTS:
4169 case INT8_ELEMENTS: 4114 case INT8_ELEMENTS:
4170 case UINT8_ELEMENTS: 4115 case UINT8_ELEMENTS:
4171 case UINT8_CLAMPED_ELEMENTS: 4116 case UINT8_CLAMPED_ELEMENTS:
4172 __ movb(operand, value); 4117 __ movb(operand, value);
4173 break; 4118 break;
4174 case EXTERNAL_SHORT_ELEMENTS: 4119 case EXTERNAL_INT16_ELEMENTS:
4175 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4120 case EXTERNAL_UINT16_ELEMENTS:
4176 case INT16_ELEMENTS: 4121 case INT16_ELEMENTS:
4177 case UINT16_ELEMENTS: 4122 case UINT16_ELEMENTS:
4178 __ movw(operand, value); 4123 __ movw(operand, value);
4179 break; 4124 break;
4180 case EXTERNAL_INT_ELEMENTS: 4125 case EXTERNAL_INT32_ELEMENTS:
4181 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4126 case EXTERNAL_UINT32_ELEMENTS:
4182 case INT32_ELEMENTS: 4127 case INT32_ELEMENTS:
4183 case UINT32_ELEMENTS: 4128 case UINT32_ELEMENTS:
4184 __ movl(operand, value); 4129 __ movl(operand, value);
4185 break; 4130 break;
4186 case EXTERNAL_FLOAT_ELEMENTS: 4131 case EXTERNAL_FLOAT32_ELEMENTS:
4187 case EXTERNAL_DOUBLE_ELEMENTS: 4132 case EXTERNAL_FLOAT64_ELEMENTS:
4188 case FLOAT32_ELEMENTS: 4133 case FLOAT32_ELEMENTS:
4189 case FLOAT64_ELEMENTS: 4134 case FLOAT64_ELEMENTS:
4190 case FAST_ELEMENTS: 4135 case FAST_ELEMENTS:
4191 case FAST_SMI_ELEMENTS: 4136 case FAST_SMI_ELEMENTS:
4192 case FAST_DOUBLE_ELEMENTS: 4137 case FAST_DOUBLE_ELEMENTS:
4193 case FAST_HOLEY_ELEMENTS: 4138 case FAST_HOLEY_ELEMENTS:
4194 case FAST_HOLEY_SMI_ELEMENTS: 4139 case FAST_HOLEY_SMI_ELEMENTS:
4195 case FAST_HOLEY_DOUBLE_ELEMENTS: 4140 case FAST_HOLEY_DOUBLE_ELEMENTS:
4196 case DICTIONARY_ELEMENTS: 4141 case DICTIONARY_ELEMENTS:
4197 case NON_STRICT_ARGUMENTS_ELEMENTS: 4142 case NON_STRICT_ARGUMENTS_ELEMENTS:
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4259 __ movsxlq(key_reg, key_reg); 4204 __ movsxlq(key_reg, key_reg);
4260 } 4205 }
4261 } 4206 }
4262 4207
4263 int offset = FixedArray::kHeaderSize - kHeapObjectTag; 4208 int offset = FixedArray::kHeaderSize - kHeapObjectTag;
4264 Representation representation = hinstr->value()->representation(); 4209 Representation representation = hinstr->value()->representation();
4265 4210
4266 if (representation.IsInteger32()) { 4211 if (representation.IsInteger32()) {
4267 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); 4212 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
4268 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); 4213 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS);
4214 #ifdef DEBUG
4215 Register scratch = kScratchRegister;
4216 __ Load(scratch,
4217 BuildFastArrayOperand(instr->elements(),
4218 key,
4219 FAST_ELEMENTS,
4220 offset,
4221 instr->additional_index()),
4222 Representation::Smi());
4223 __ AssertSmi(scratch);
4224 #endif
4269 // Store int value directly to upper half of the smi. 4225 // Store int value directly to upper half of the smi.
4270 STATIC_ASSERT(kSmiTag == 0); 4226 STATIC_ASSERT(kSmiTag == 0);
4271 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); 4227 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
4272 offset += kPointerSize / 2; 4228 offset += kPointerSize / 2;
4273 } 4229 }
4274 4230
4275 Operand operand = 4231 Operand operand =
4276 BuildFastArrayOperand(instr->elements(), 4232 BuildFastArrayOperand(instr->elements(),
4277 key, 4233 key,
4278 FAST_ELEMENTS, 4234 FAST_ELEMENTS,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
4381 Register temp = ToRegister(instr->temp()); 4337 Register temp = ToRegister(instr->temp());
4382 Label no_memento_found; 4338 Label no_memento_found;
4383 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); 4339 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
4384 DeoptimizeIf(equal, instr->environment()); 4340 DeoptimizeIf(equal, instr->environment());
4385 __ bind(&no_memento_found); 4341 __ bind(&no_memento_found);
4386 } 4342 }
4387 4343
4388 4344
4389 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4345 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4390 ASSERT(ToRegister(instr->context()).is(rsi)); 4346 ASSERT(ToRegister(instr->context()).is(rsi));
4391 if (FLAG_new_string_add) { 4347 ASSERT(ToRegister(instr->left()).is(rdx));
4392 ASSERT(ToRegister(instr->left()).is(rdx)); 4348 ASSERT(ToRegister(instr->right()).is(rax));
4393 ASSERT(ToRegister(instr->right()).is(rax)); 4349 StringAddStub stub(instr->hydrogen()->flags(),
4394 NewStringAddStub stub(instr->hydrogen()->flags(), 4350 instr->hydrogen()->pretenure_flag());
4395 isolate()->heap()->GetPretenureMode()); 4351 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4396 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4397 } else {
4398 EmitPushTaggedOperand(instr->left());
4399 EmitPushTaggedOperand(instr->right());
4400 StringAddStub stub(instr->hydrogen()->flags());
4401 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4402 }
4403 } 4352 }
4404 4353
4405 4354
4406 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 4355 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4407 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { 4356 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode {
4408 public: 4357 public:
4409 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 4358 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4410 : LDeferredCode(codegen), instr_(instr) { } 4359 : LDeferredCode(codegen), instr_(instr) { }
4411 virtual void Generate() V8_OVERRIDE { 4360 virtual void Generate() V8_OVERRIDE {
4412 codegen()->DoDeferredStringCharCodeAt(instr_); 4361 codegen()->DoDeferredStringCharCodeAt(instr_);
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
5135 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5084 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5136 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5085 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5137 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); 5086 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
5138 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5087 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5139 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5088 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5140 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); 5089 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE);
5141 } 5090 }
5142 5091
5143 if (instr->size()->IsConstantOperand()) { 5092 if (instr->size()->IsConstantOperand()) {
5144 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5093 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5145 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 5094 if (size <= Page::kMaxRegularHeapObjectSize) {
5095 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
5096 } else {
5097 __ jmp(deferred->entry());
5098 }
5146 } else { 5099 } else {
5147 Register size = ToRegister(instr->size()); 5100 Register size = ToRegister(instr->size());
5148 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 5101 __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
5149 } 5102 }
5150 5103
5151 __ bind(deferred->exit()); 5104 __ bind(deferred->exit());
5152 5105
5153 if (instr->hydrogen()->MustPrefillWithFiller()) { 5106 if (instr->hydrogen()->MustPrefillWithFiller()) {
5154 if (instr->size()->IsConstantOperand()) { 5107 if (instr->size()->IsConstantOperand()) {
5155 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5108 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
5636 FixedArray::kHeaderSize - kPointerSize)); 5589 FixedArray::kHeaderSize - kPointerSize));
5637 __ bind(&done); 5590 __ bind(&done);
5638 } 5591 }
5639 5592
5640 5593
5641 #undef __ 5594 #undef __
5642 5595
5643 } } // namespace v8::internal 5596 } } // namespace v8::internal
5644 5597
5645 #endif // V8_TARGET_ARCH_X64 5598 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/ic-x64.cc ('k') | src/x64/lithium-gap-resolver-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698