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

Side by Side Diff: src/arm/lithium-codegen-arm.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/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.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. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 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 LCodeGen::Abort(BailoutReason reason) { 93 void LCodeGen::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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 200
201 if (info()->saves_caller_doubles()) { 201 if (info()->saves_caller_doubles()) {
202 SaveCallerDoubles(); 202 SaveCallerDoubles();
203 } 203 }
204 204
205 // Possibly allocate a local context. 205 // Possibly allocate a local context.
206 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 206 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
207 if (heap_slots > 0) { 207 if (heap_slots > 0) {
208 Comment(";;; Allocate local context"); 208 Comment(";;; Allocate local context");
209 // Argument to NewContext is the function, which is in r1. 209 // Argument to NewContext is the function, which is in r1.
210 __ push(r1);
211 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 210 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
212 FastNewContextStub stub(heap_slots); 211 FastNewContextStub stub(heap_slots);
213 __ CallStub(&stub); 212 __ CallStub(&stub);
214 } else { 213 } else {
214 __ push(r1);
215 __ CallRuntime(Runtime::kNewFunctionContext, 1); 215 __ CallRuntime(Runtime::kNewFunctionContext, 1);
216 } 216 }
217 RecordSafepoint(Safepoint::kNoLazyDeopt); 217 RecordSafepoint(Safepoint::kNoLazyDeopt);
218 // Context is returned in both r0 and cp. It replaces the context 218 // Context is returned in both r0 and cp. It replaces the context
219 // passed to us. It's saved in the stack and kept live in cp. 219 // passed to us. It's saved in the stack and kept live in cp.
220 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 220 __ mov(cp, r0);
221 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset));
221 // Copy any necessary parameters into the context. 222 // Copy any necessary parameters into the context.
222 int num_parameters = scope()->num_parameters(); 223 int num_parameters = scope()->num_parameters();
223 for (int i = 0; i < num_parameters; i++) { 224 for (int i = 0; i < num_parameters; i++) {
224 Variable* var = scope()->parameter(i); 225 Variable* var = scope()->parameter(i);
225 if (var->IsContextSlot()) { 226 if (var->IsContextSlot()) {
226 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 227 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
227 (num_parameters - 1 - i) * kPointerSize; 228 (num_parameters - 1 - i) * kPointerSize;
228 // Load parameter from stack. 229 // Load parameter from stack.
229 __ ldr(r0, MemOperand(fp, parameter_offset)); 230 __ ldr(r0, MemOperand(fp, parameter_offset));
230 // Store it in the context. 231 // Store it in the context.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 270
270 271
271 bool LCodeGen::GenerateDeferredCode() { 272 bool LCodeGen::GenerateDeferredCode() {
272 ASSERT(is_generating()); 273 ASSERT(is_generating());
273 if (deferred_.length() > 0) { 274 if (deferred_.length() > 0) {
274 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 275 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
275 LDeferredCode* code = deferred_[i]; 276 LDeferredCode* code = deferred_[i];
276 277
277 HValue* value = 278 HValue* value =
278 instructions_->at(code->instruction_index())->hydrogen_value(); 279 instructions_->at(code->instruction_index())->hydrogen_value();
279 RecordAndWritePosition(value->position()); 280 RecordAndWritePosition(
281 chunk()->graph()->SourcePositionToScriptPosition(value->position()));
280 282
281 Comment(";;; <@%d,#%d> " 283 Comment(";;; <@%d,#%d> "
282 "-------------------- Deferred %s --------------------", 284 "-------------------- Deferred %s --------------------",
283 code->instruction_index(), 285 code->instruction_index(),
284 code->instr()->hydrogen_value()->id(), 286 code->instr()->hydrogen_value()->id(),
285 code->instr()->Mnemonic()); 287 code->instr()->Mnemonic());
286 __ bind(code->entry()); 288 __ bind(code->entry());
287 if (NeedsDeferredFrame()) { 289 if (NeedsDeferredFrame()) {
288 Comment(";;; Build frame"); 290 Comment(";;; Build frame");
289 ASSERT(!frame_is_built_); 291 ASSERT(!frame_is_built_);
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 900 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
899 int length = deoptimizations_.length(); 901 int length = deoptimizations_.length();
900 if (length == 0) return; 902 if (length == 0) return;
901 Handle<DeoptimizationInputData> data = 903 Handle<DeoptimizationInputData> data =
902 factory()->NewDeoptimizationInputData(length, TENURED); 904 factory()->NewDeoptimizationInputData(length, TENURED);
903 905
904 Handle<ByteArray> translations = 906 Handle<ByteArray> translations =
905 translations_.CreateByteArray(isolate()->factory()); 907 translations_.CreateByteArray(isolate()->factory());
906 data->SetTranslationByteArray(*translations); 908 data->SetTranslationByteArray(*translations);
907 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 909 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
910 data->SetOptimizationId(Smi::FromInt(info_->optimization_id()));
911 if (info_->IsOptimizing()) {
912 // Reference to shared function info does not change between phases.
913 AllowDeferredHandleDereference allow_handle_dereference;
914 data->SetSharedFunctionInfo(*info_->shared_info());
915 } else {
916 data->SetSharedFunctionInfo(Smi::FromInt(0));
917 }
908 918
909 Handle<FixedArray> literals = 919 Handle<FixedArray> literals =
910 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 920 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
911 { AllowDeferredHandleDereference copy_handles; 921 { AllowDeferredHandleDereference copy_handles;
912 for (int i = 0; i < deoptimization_literals_.length(); i++) { 922 for (int i = 0; i < deoptimization_literals_.length(); i++) {
913 literals->set(i, *deoptimization_literals_[i]); 923 literals->set(i, *deoptimization_literals_[i]);
914 } 924 }
915 data->SetLiteralArray(*literals); 925 data->SetLiteralArray(*literals);
916 } 926 }
917 927
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 1082
1073 void LCodeGen::DoParameter(LParameter* instr) { 1083 void LCodeGen::DoParameter(LParameter* instr) {
1074 // Nothing to do. 1084 // Nothing to do.
1075 } 1085 }
1076 1086
1077 1087
1078 void LCodeGen::DoCallStub(LCallStub* instr) { 1088 void LCodeGen::DoCallStub(LCallStub* instr) {
1079 ASSERT(ToRegister(instr->context()).is(cp)); 1089 ASSERT(ToRegister(instr->context()).is(cp));
1080 ASSERT(ToRegister(instr->result()).is(r0)); 1090 ASSERT(ToRegister(instr->result()).is(r0));
1081 switch (instr->hydrogen()->major_key()) { 1091 switch (instr->hydrogen()->major_key()) {
1082 case CodeStub::RegExpConstructResult: {
1083 RegExpConstructResultStub stub;
1084 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1085 break;
1086 }
1087 case CodeStub::RegExpExec: { 1092 case CodeStub::RegExpExec: {
1088 RegExpExecStub stub; 1093 RegExpExecStub stub;
1089 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1094 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1090 break; 1095 break;
1091 } 1096 }
1092 case CodeStub::SubString: { 1097 case CodeStub::SubString: {
1093 SubStringStub stub; 1098 SubStringStub stub;
1094 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 1099 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
1095 break; 1100 break;
1096 } 1101 }
(...skipping 10 matching lines...) Expand all
1107 1112
1108 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 1113 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
1109 GenerateOsrPrologue(); 1114 GenerateOsrPrologue();
1110 } 1115 }
1111 1116
1112 1117
1113 void LCodeGen::DoModI(LModI* instr) { 1118 void LCodeGen::DoModI(LModI* instr) {
1114 HMod* hmod = instr->hydrogen(); 1119 HMod* hmod = instr->hydrogen();
1115 HValue* left = hmod->left(); 1120 HValue* left = hmod->left();
1116 HValue* right = hmod->right(); 1121 HValue* right = hmod->right();
1117 if (hmod->HasPowerOf2Divisor()) { 1122 if (hmod->RightIsPowerOf2()) {
1118 // TODO(svenpanne) We should really do the strength reduction on the 1123 // TODO(svenpanne) We should really do the strength reduction on the
1119 // Hydrogen level. 1124 // Hydrogen level.
1120 Register left_reg = ToRegister(instr->left()); 1125 Register left_reg = ToRegister(instr->left());
1121 Register result_reg = ToRegister(instr->result()); 1126 Register result_reg = ToRegister(instr->result());
1122 1127
1123 // Note: The code below even works when right contains kMinInt. 1128 // Note: The code below even works when right contains kMinInt.
1124 int32_t divisor = Abs(right->GetInteger32Constant()); 1129 int32_t divisor = Abs(right->GetInteger32Constant());
1125 1130
1126 Label left_is_not_negative, done; 1131 Label left_is_not_negative, done;
1127 if (left->CanBeNegative()) { 1132 if (left->CanBeNegative()) {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 // This sequence could be replaced with 'mls' when 1342 // This sequence could be replaced with 'mls' when
1338 // it gets implemented. 1343 // it gets implemented.
1339 __ mul(scratch, result, ip); 1344 __ mul(scratch, result, ip);
1340 __ sub(remainder, dividend, scratch); 1345 __ sub(remainder, dividend, scratch);
1341 } 1346 }
1342 } 1347 }
1343 } 1348 }
1344 1349
1345 1350
1346 void LCodeGen::DoDivI(LDivI* instr) { 1351 void LCodeGen::DoDivI(LDivI* instr) {
1347 if (instr->hydrogen()->HasPowerOf2Divisor()) { 1352 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) {
1348 const Register dividend = ToRegister(instr->left()); 1353 Register dividend = ToRegister(instr->left());
1349 const Register result = ToRegister(instr->result()); 1354 HDiv* hdiv = instr->hydrogen();
1350 int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant(); 1355 int32_t divisor = hdiv->right()->GetInteger32Constant();
1351 int32_t test_value = 0; 1356 Register result = ToRegister(instr->result());
1352 int32_t power = 0; 1357 ASSERT(!result.is(dividend));
1353 1358
1354 if (divisor > 0) { 1359 // Check for (0 / -x) that will produce negative zero.
1355 test_value = divisor - 1; 1360 if (hdiv->left()->RangeCanInclude(0) && divisor < 0 &&
1356 power = WhichPowerOf2(divisor); 1361 hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1362 __ cmp(dividend, Operand::Zero());
1363 DeoptimizeIf(eq, instr->environment());
1364 }
1365 // Check for (kMinInt / -1).
1366 if (hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1 &&
1367 hdiv->CheckFlag(HValue::kCanOverflow)) {
1368 __ cmp(dividend, Operand(kMinInt));
1369 DeoptimizeIf(eq, instr->environment());
1370 }
1371 // Deoptimize if remainder will not be 0.
1372 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1373 Abs(divisor) != 1) {
1374 __ tst(dividend, Operand(Abs(divisor) - 1));
1375 DeoptimizeIf(ne, instr->environment());
1376 }
1377 if (divisor == -1) { // Nice shortcut, not needed for correctness.
1378 __ rsb(result, dividend, Operand(0));
1379 return;
1380 }
1381 int32_t shift = WhichPowerOf2(Abs(divisor));
1382 if (shift == 0) {
1383 __ mov(result, dividend);
1384 } else if (shift == 1) {
1385 __ add(result, dividend, Operand(dividend, LSR, 31));
1357 } else { 1386 } else {
1358 // Check for (0 / -x) that will produce negative zero. 1387 __ mov(result, Operand(dividend, ASR, 31));
1359 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1388 __ add(result, dividend, Operand(result, LSR, 32 - shift));
1360 __ cmp(dividend, Operand::Zero());
1361 DeoptimizeIf(eq, instr->environment());
1362 }
1363 // Check for (kMinInt / -1).
1364 if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1365 __ cmp(dividend, Operand(kMinInt));
1366 DeoptimizeIf(eq, instr->environment());
1367 }
1368 test_value = - divisor - 1;
1369 power = WhichPowerOf2(-divisor);
1370 } 1389 }
1371 1390 if (shift > 0) __ mov(result, Operand(result, ASR, shift));
1372 if (test_value != 0) { 1391 if (divisor < 0) __ rsb(result, result, Operand(0));
1373 if (instr->hydrogen()->CheckFlag(
1374 HInstruction::kAllUsesTruncatingToInt32)) {
1375 __ sub(result, dividend, Operand::Zero(), SetCC);
1376 __ rsb(result, result, Operand::Zero(), LeaveCC, lt);
1377 __ mov(result, Operand(result, ASR, power));
1378 if (divisor > 0) __ rsb(result, result, Operand::Zero(), LeaveCC, lt);
1379 if (divisor < 0) __ rsb(result, result, Operand::Zero(), LeaveCC, gt);
1380 return; // Don't fall through to "__ rsb" below.
1381 } else {
1382 // Deoptimize if remainder is not 0.
1383 __ tst(dividend, Operand(test_value));
1384 DeoptimizeIf(ne, instr->environment());
1385 __ mov(result, Operand(dividend, ASR, power));
1386 if (divisor < 0) __ rsb(result, result, Operand(0));
1387 }
1388 } else {
1389 if (divisor < 0) {
1390 __ rsb(result, dividend, Operand(0));
1391 } else {
1392 __ Move(result, dividend);
1393 }
1394 }
1395
1396 return; 1392 return;
1397 } 1393 }
1398 1394
1399 const Register left = ToRegister(instr->left()); 1395 const Register left = ToRegister(instr->left());
1400 const Register right = ToRegister(instr->right()); 1396 const Register right = ToRegister(instr->right());
1401 const Register result = ToRegister(instr->result()); 1397 const Register result = ToRegister(instr->result());
1402 1398
1403 // Check for x / 0. 1399 // Check for x / 0.
1404 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1400 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
1405 __ cmp(right, Operand::Zero()); 1401 __ cmp(right, Operand::Zero());
1406 DeoptimizeIf(eq, instr->environment()); 1402 DeoptimizeIf(eq, instr->environment());
1407 } 1403 }
1408 1404
1409 // Check for (0 / -x) that will produce negative zero. 1405 // Check for (0 / -x) that will produce negative zero.
1410 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1406 if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1411 Label positive; 1407 Label positive;
1412 if (!instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 1408 if (!instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) {
1413 // Do the test only if it hadn't be done above. 1409 // Do the test only if it hadn't be done above.
1414 __ cmp(right, Operand::Zero()); 1410 __ cmp(right, Operand::Zero());
1415 } 1411 }
1416 __ b(pl, &positive); 1412 __ b(pl, &positive);
1417 __ cmp(left, Operand::Zero()); 1413 __ cmp(left, Operand::Zero());
1418 DeoptimizeIf(eq, instr->environment()); 1414 DeoptimizeIf(eq, instr->environment());
1419 __ bind(&positive); 1415 __ bind(&positive);
1420 } 1416 }
1421 1417
1422 // Check for (kMinInt / -1). 1418 // Check for (kMinInt / -1).
1423 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow) && 1419 if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow) &&
1424 (!CpuFeatures::IsSupported(SUDIV) || 1420 (!CpuFeatures::IsSupported(SUDIV) ||
1425 !instr->hydrogen()->CheckFlag(HValue::kAllUsesTruncatingToInt32))) { 1421 !instr->hydrogen_value()->CheckFlag(
1422 HValue::kAllUsesTruncatingToInt32))) {
1426 // We don't need to check for overflow when truncating with sdiv 1423 // We don't need to check for overflow when truncating with sdiv
1427 // support because, on ARM, sdiv kMinInt, -1 -> kMinInt. 1424 // support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
1428 __ cmp(left, Operand(kMinInt)); 1425 __ cmp(left, Operand(kMinInt));
1429 __ cmp(right, Operand(-1), eq); 1426 __ cmp(right, Operand(-1), eq);
1430 DeoptimizeIf(eq, instr->environment()); 1427 DeoptimizeIf(eq, instr->environment());
1431 } 1428 }
1432 1429
1433 if (CpuFeatures::IsSupported(SUDIV)) { 1430 if (CpuFeatures::IsSupported(SUDIV)) {
1434 CpuFeatureScope scope(masm(), SUDIV); 1431 CpuFeatureScope scope(masm(), SUDIV);
1435 __ sdiv(result, left, right); 1432 __ sdiv(result, left, right);
1436 1433
1437 if (!instr->hydrogen()->CheckFlag( 1434 if (!instr->hydrogen_value()->CheckFlag(
1438 HInstruction::kAllUsesTruncatingToInt32)) { 1435 HInstruction::kAllUsesTruncatingToInt32)) {
1439 // Compute remainder and deopt if it's not zero. 1436 // Compute remainder and deopt if it's not zero.
1440 const Register remainder = scratch0(); 1437 const Register remainder = scratch0();
1441 __ mls(remainder, result, right, left); 1438 __ mls(remainder, result, right, left);
1442 __ cmp(remainder, Operand::Zero()); 1439 __ cmp(remainder, Operand::Zero());
1443 DeoptimizeIf(ne, instr->environment()); 1440 DeoptimizeIf(ne, instr->environment());
1444 } 1441 }
1445 } else { 1442 } else {
1446 const DoubleRegister vleft = ToDoubleRegister(instr->temp()); 1443 const DoubleRegister vleft = ToDoubleRegister(instr->temp());
1447 const DoubleRegister vright = double_scratch0(); 1444 const DoubleRegister vright = double_scratch0();
1448 __ vmov(double_scratch0().low(), left); 1445 __ vmov(double_scratch0().low(), left);
1449 __ vcvt_f64_s32(vleft, double_scratch0().low()); 1446 __ vcvt_f64_s32(vleft, double_scratch0().low());
1450 __ vmov(double_scratch0().low(), right); 1447 __ vmov(double_scratch0().low(), right);
1451 __ vcvt_f64_s32(vright, double_scratch0().low()); 1448 __ vcvt_f64_s32(vright, double_scratch0().low());
1452 __ vdiv(vleft, vleft, vright); // vleft now contains the result. 1449 __ vdiv(vleft, vleft, vright); // vleft now contains the result.
1453 __ vcvt_s32_f64(double_scratch0().low(), vleft); 1450 __ vcvt_s32_f64(double_scratch0().low(), vleft);
1454 __ vmov(result, double_scratch0().low()); 1451 __ vmov(result, double_scratch0().low());
1455 1452
1456 if (!instr->hydrogen()->CheckFlag( 1453 if (!instr->hydrogen_value()->CheckFlag(
1457 HInstruction::kAllUsesTruncatingToInt32)) { 1454 HInstruction::kAllUsesTruncatingToInt32)) {
1458 // Deopt if exact conversion to integer was not possible. 1455 // Deopt if exact conversion to integer was not possible.
1459 // Use vright as scratch register. 1456 // Use vright as scratch register.
1460 __ vcvt_f64_s32(double_scratch0(), double_scratch0().low()); 1457 __ vcvt_f64_s32(double_scratch0(), double_scratch0().low());
1461 __ VFPCompareAndSetFlags(vleft, double_scratch0()); 1458 __ VFPCompareAndSetFlags(vleft, double_scratch0());
1462 DeoptimizeIf(ne, instr->environment()); 1459 DeoptimizeIf(ne, instr->environment());
1463 } 1460 }
1464 } 1461 }
1465 } 1462 }
1466 1463
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1860 } 1857 }
1861 1858
1862 1859
1863 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1860 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1864 Register result = ToRegister(instr->result()); 1861 Register result = ToRegister(instr->result());
1865 Register map = ToRegister(instr->value()); 1862 Register map = ToRegister(instr->value());
1866 __ EnumLength(result, map); 1863 __ EnumLength(result, map);
1867 } 1864 }
1868 1865
1869 1866
1870 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1871 Register result = ToRegister(instr->result());
1872 Register input = ToRegister(instr->value());
1873
1874 // Load map into |result|.
1875 __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset));
1876 // Load the map's "bit field 2" into |result|. We only need the first byte,
1877 // but the following bit field extraction takes care of that anyway.
1878 __ ldr(result, FieldMemOperand(result, Map::kBitField2Offset));
1879 // Retrieve elements_kind from bit field 2.
1880 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount);
1881 }
1882
1883
1884 void LCodeGen::DoValueOf(LValueOf* instr) {
1885 Register input = ToRegister(instr->value());
1886 Register result = ToRegister(instr->result());
1887 Register map = ToRegister(instr->temp());
1888 Label done;
1889
1890 if (!instr->hydrogen()->value()->IsHeapObject()) {
1891 // If the object is a smi return the object.
1892 __ SmiTst(input);
1893 __ Move(result, input, eq);
1894 __ b(eq, &done);
1895 }
1896
1897 // If the object is not a value type, return the object.
1898 __ CompareObjectType(input, map, map, JS_VALUE_TYPE);
1899 __ Move(result, input, ne);
1900 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset), eq);
1901
1902 __ bind(&done);
1903 }
1904
1905
1906 void LCodeGen::DoDateField(LDateField* instr) { 1867 void LCodeGen::DoDateField(LDateField* instr) {
1907 Register object = ToRegister(instr->date()); 1868 Register object = ToRegister(instr->date());
1908 Register result = ToRegister(instr->result()); 1869 Register result = ToRegister(instr->result());
1909 Register scratch = ToRegister(instr->temp()); 1870 Register scratch = ToRegister(instr->temp());
1910 Smi* index = instr->index(); 1871 Smi* index = instr->index();
1911 Label runtime, done; 1872 Label runtime, done;
1912 ASSERT(object.is(result)); 1873 ASSERT(object.is(result));
1913 ASSERT(object.is(r0)); 1874 ASSERT(object.is(r0));
1914 ASSERT(!scratch.is(scratch0())); 1875 ASSERT(!scratch.is(scratch0()));
1915 ASSERT(!scratch.is(object)); 1876 ASSERT(!scratch.is(object));
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2011 1972
2012 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding); 1973 MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
2013 if (encoding == String::ONE_BYTE_ENCODING) { 1974 if (encoding == String::ONE_BYTE_ENCODING) {
2014 __ strb(value, operand); 1975 __ strb(value, operand);
2015 } else { 1976 } else {
2016 __ strh(value, operand); 1977 __ strh(value, operand);
2017 } 1978 }
2018 } 1979 }
2019 1980
2020 1981
2021 void LCodeGen::DoThrow(LThrow* instr) {
2022 __ push(ToRegister(instr->value()));
2023 ASSERT(ToRegister(instr->context()).is(cp));
2024 CallRuntime(Runtime::kThrow, 1, instr);
2025
2026 if (FLAG_debug_code) {
2027 __ stop("Unreachable code.");
2028 }
2029 }
2030
2031
2032 void LCodeGen::DoAddI(LAddI* instr) { 1982 void LCodeGen::DoAddI(LAddI* instr) {
2033 LOperand* left = instr->left(); 1983 LOperand* left = instr->left();
2034 LOperand* right = instr->right(); 1984 LOperand* right = instr->right();
2035 LOperand* result = instr->result(); 1985 LOperand* result = instr->result();
2036 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 1986 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
2037 SBit set_cond = can_overflow ? SetCC : LeaveCC; 1987 SBit set_cond = can_overflow ? SetCC : LeaveCC;
2038 1988
2039 if (right->IsStackSlot() || right->IsArgument()) { 1989 if (right->IsStackSlot() || right->IsArgument()) {
2040 Register right_reg = EmitLoadRegister(right, ip); 1990 Register right_reg = EmitLoadRegister(right, ip);
2041 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); 1991 __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond);
(...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after
3138 __ bind(&done); 3088 __ bind(&done);
3139 } 3089 }
3140 3090
3141 3091
3142 void LCodeGen::DoLoadRoot(LLoadRoot* instr) { 3092 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3143 Register result = ToRegister(instr->result()); 3093 Register result = ToRegister(instr->result());
3144 __ LoadRoot(result, instr->index()); 3094 __ LoadRoot(result, instr->index());
3145 } 3095 }
3146 3096
3147 3097
3148 void LCodeGen::DoLoadExternalArrayPointer(
3149 LLoadExternalArrayPointer* instr) {
3150 Register to_reg = ToRegister(instr->result());
3151 Register from_reg = ToRegister(instr->object());
3152 __ ldr(to_reg, FieldMemOperand(from_reg,
3153 ExternalArray::kExternalPointerOffset));
3154 }
3155
3156
3157 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 3098 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
3158 Register arguments = ToRegister(instr->arguments()); 3099 Register arguments = ToRegister(instr->arguments());
3159 Register result = ToRegister(instr->result()); 3100 Register result = ToRegister(instr->result());
3160 // There are two words between the frame pointer and the last argument. 3101 // There are two words between the frame pointer and the last argument.
3161 // Subtracting from length accounts for one of them add one more. 3102 // Subtracting from length accounts for one of them add one more.
3162 if (instr->length()->IsConstantOperand()) { 3103 if (instr->length()->IsConstantOperand()) {
3163 int const_length = ToInteger32(LConstantOperand::cast(instr->length())); 3104 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
3164 if (instr->index()->IsConstantOperand()) { 3105 if (instr->index()->IsConstantOperand()) {
3165 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3106 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3166 int index = (const_length - const_index) + 1; 3107 int index = (const_length - const_index) + 1;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3205 key = ToRegister(instr->key()); 3146 key = ToRegister(instr->key());
3206 } 3147 }
3207 int element_size_shift = ElementsKindToShiftSize(elements_kind); 3148 int element_size_shift = ElementsKindToShiftSize(elements_kind);
3208 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 3149 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3209 ? (element_size_shift - kSmiTagSize) : element_size_shift; 3150 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3210 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) 3151 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
3211 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 3152 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
3212 : 0; 3153 : 0;
3213 3154
3214 3155
3215 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3156 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
3216 elements_kind == FLOAT32_ELEMENTS || 3157 elements_kind == FLOAT32_ELEMENTS ||
3217 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || 3158 elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
3218 elements_kind == FLOAT64_ELEMENTS) { 3159 elements_kind == FLOAT64_ELEMENTS) {
3219 int base_offset = 3160 int base_offset =
3220 (instr->additional_index() << element_size_shift) + additional_offset; 3161 (instr->additional_index() << element_size_shift) + additional_offset;
3221 DwVfpRegister result = ToDoubleRegister(instr->result()); 3162 DwVfpRegister result = ToDoubleRegister(instr->result());
3222 Operand operand = key_is_constant 3163 Operand operand = key_is_constant
3223 ? Operand(constant_key << element_size_shift) 3164 ? Operand(constant_key << element_size_shift)
3224 : Operand(key, LSL, shift_size); 3165 : Operand(key, LSL, shift_size);
3225 __ add(scratch0(), external_pointer, operand); 3166 __ add(scratch0(), external_pointer, operand);
3226 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3167 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
3227 elements_kind == FLOAT32_ELEMENTS) { 3168 elements_kind == FLOAT32_ELEMENTS) {
3228 __ vldr(double_scratch0().low(), scratch0(), base_offset); 3169 __ vldr(double_scratch0().low(), scratch0(), base_offset);
3229 __ vcvt_f64_f32(result, double_scratch0().low()); 3170 __ vcvt_f64_f32(result, double_scratch0().low());
3230 } else { // loading doubles, not floats. 3171 } else { // loading doubles, not floats.
3231 __ vldr(result, scratch0(), base_offset); 3172 __ vldr(result, scratch0(), base_offset);
3232 } 3173 }
3233 } else { 3174 } else {
3234 Register result = ToRegister(instr->result()); 3175 Register result = ToRegister(instr->result());
3235 MemOperand mem_operand = PrepareKeyedOperand( 3176 MemOperand mem_operand = PrepareKeyedOperand(
3236 key, external_pointer, key_is_constant, constant_key, 3177 key, external_pointer, key_is_constant, constant_key,
3237 element_size_shift, shift_size, 3178 element_size_shift, shift_size,
3238 instr->additional_index(), additional_offset); 3179 instr->additional_index(), additional_offset);
3239 switch (elements_kind) { 3180 switch (elements_kind) {
3240 case EXTERNAL_BYTE_ELEMENTS: 3181 case EXTERNAL_INT8_ELEMENTS:
3241 case INT8_ELEMENTS: 3182 case INT8_ELEMENTS:
3242 __ ldrsb(result, mem_operand); 3183 __ ldrsb(result, mem_operand);
3243 break; 3184 break;
3244 case EXTERNAL_PIXEL_ELEMENTS: 3185 case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
3245 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3186 case EXTERNAL_UINT8_ELEMENTS:
3246 case UINT8_ELEMENTS: 3187 case UINT8_ELEMENTS:
3247 case UINT8_CLAMPED_ELEMENTS: 3188 case UINT8_CLAMPED_ELEMENTS:
3248 __ ldrb(result, mem_operand); 3189 __ ldrb(result, mem_operand);
3249 break; 3190 break;
3250 case EXTERNAL_SHORT_ELEMENTS: 3191 case EXTERNAL_INT16_ELEMENTS:
3251 case INT16_ELEMENTS: 3192 case INT16_ELEMENTS:
3252 __ ldrsh(result, mem_operand); 3193 __ ldrsh(result, mem_operand);
3253 break; 3194 break;
3254 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3195 case EXTERNAL_UINT16_ELEMENTS:
3255 case UINT16_ELEMENTS: 3196 case UINT16_ELEMENTS:
3256 __ ldrh(result, mem_operand); 3197 __ ldrh(result, mem_operand);
3257 break; 3198 break;
3258 case EXTERNAL_INT_ELEMENTS: 3199 case EXTERNAL_INT32_ELEMENTS:
3259 case INT32_ELEMENTS: 3200 case INT32_ELEMENTS:
3260 __ ldr(result, mem_operand); 3201 __ ldr(result, mem_operand);
3261 break; 3202 break;
3262 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3203 case EXTERNAL_UINT32_ELEMENTS:
3263 case UINT32_ELEMENTS: 3204 case UINT32_ELEMENTS:
3264 __ ldr(result, mem_operand); 3205 __ ldr(result, mem_operand);
3265 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3206 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3266 __ cmp(result, Operand(0x80000000)); 3207 __ cmp(result, Operand(0x80000000));
3267 DeoptimizeIf(cs, instr->environment()); 3208 DeoptimizeIf(cs, instr->environment());
3268 } 3209 }
3269 break; 3210 break;
3270 case FLOAT32_ELEMENTS: 3211 case FLOAT32_ELEMENTS:
3271 case FLOAT64_ELEMENTS: 3212 case FLOAT64_ELEMENTS:
3272 case EXTERNAL_FLOAT_ELEMENTS: 3213 case EXTERNAL_FLOAT32_ELEMENTS:
3273 case EXTERNAL_DOUBLE_ELEMENTS: 3214 case EXTERNAL_FLOAT64_ELEMENTS:
3274 case FAST_HOLEY_DOUBLE_ELEMENTS: 3215 case FAST_HOLEY_DOUBLE_ELEMENTS:
3275 case FAST_HOLEY_ELEMENTS: 3216 case FAST_HOLEY_ELEMENTS:
3276 case FAST_HOLEY_SMI_ELEMENTS: 3217 case FAST_HOLEY_SMI_ELEMENTS:
3277 case FAST_DOUBLE_ELEMENTS: 3218 case FAST_DOUBLE_ELEMENTS:
3278 case FAST_ELEMENTS: 3219 case FAST_ELEMENTS:
3279 case FAST_SMI_ELEMENTS: 3220 case FAST_SMI_ELEMENTS:
3280 case DICTIONARY_ELEMENTS: 3221 case DICTIONARY_ELEMENTS:
3281 case NON_STRICT_ARGUMENTS_ELEMENTS: 3222 case NON_STRICT_ARGUMENTS_ELEMENTS:
3282 UNREACHABLE(); 3223 UNREACHABLE();
3283 break; 3224 break;
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
3481 Register receiver = ToRegister(instr->receiver()); 3422 Register receiver = ToRegister(instr->receiver());
3482 Register function = ToRegister(instr->function()); 3423 Register function = ToRegister(instr->function());
3483 Register result = ToRegister(instr->result()); 3424 Register result = ToRegister(instr->result());
3484 Register scratch = scratch0(); 3425 Register scratch = scratch0();
3485 3426
3486 // If the receiver is null or undefined, we have to pass the global 3427 // If the receiver is null or undefined, we have to pass the global
3487 // object as a receiver to normal functions. Values have to be 3428 // object as a receiver to normal functions. Values have to be
3488 // passed unchanged to builtins and strict-mode functions. 3429 // passed unchanged to builtins and strict-mode functions.
3489 Label global_object, result_in_receiver; 3430 Label global_object, result_in_receiver;
3490 3431
3491 // Do not transform the receiver to object for strict mode 3432 if (!instr->hydrogen()->known_function()) {
3492 // functions. 3433 // Do not transform the receiver to object for strict mode
3493 __ ldr(scratch, 3434 // functions.
3494 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3435 __ ldr(scratch,
3495 __ ldr(scratch, 3436 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
3496 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); 3437 __ ldr(scratch,
3497 __ tst(scratch, 3438 FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset));
3498 Operand(1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize))); 3439 int mask = 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize);
3499 __ b(ne, &result_in_receiver); 3440 __ tst(scratch, Operand(mask));
3441 __ b(ne, &result_in_receiver);
3500 3442
3501 // Do not transform the receiver to object for builtins. 3443 // Do not transform the receiver to object for builtins.
3502 __ tst(scratch, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); 3444 __ tst(scratch, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
3503 __ b(ne, &result_in_receiver); 3445 __ b(ne, &result_in_receiver);
3446 }
3504 3447
3505 // Normal function. Replace undefined or null with global receiver. 3448 // Normal function. Replace undefined or null with global receiver.
3506 __ LoadRoot(scratch, Heap::kNullValueRootIndex); 3449 __ LoadRoot(scratch, Heap::kNullValueRootIndex);
3507 __ cmp(receiver, scratch); 3450 __ cmp(receiver, scratch);
3508 __ b(eq, &global_object); 3451 __ b(eq, &global_object);
3509 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 3452 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
3510 __ cmp(receiver, scratch); 3453 __ cmp(receiver, scratch);
3511 __ b(eq, &global_object); 3454 __ b(eq, &global_object);
3512 3455
3513 // Deoptimize if the receiver is not a JS object. 3456 // Deoptimize if the receiver is not a JS object.
3514 __ SmiTst(receiver); 3457 __ SmiTst(receiver);
3515 DeoptimizeIf(eq, instr->environment()); 3458 DeoptimizeIf(eq, instr->environment());
3516 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); 3459 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE);
3517 DeoptimizeIf(lt, instr->environment()); 3460 DeoptimizeIf(lt, instr->environment());
3461
3518 __ b(&result_in_receiver); 3462 __ b(&result_in_receiver);
3519
3520 __ bind(&global_object); 3463 __ bind(&global_object);
3521 __ ldr(receiver, FieldMemOperand(function, JSFunction::kContextOffset)); 3464 __ ldr(result, FieldMemOperand(function, JSFunction::kContextOffset));
3522 __ ldr(receiver, 3465 __ ldr(result,
3523 ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX)); 3466 ContextOperand(result, Context::GLOBAL_OBJECT_INDEX));
3524 __ ldr(receiver, 3467 __ ldr(result,
3525 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); 3468 FieldMemOperand(result, GlobalObject::kGlobalReceiverOffset));
3526 3469
3527 if (result.is(receiver)) { 3470 if (result.is(receiver)) {
3528 __ bind(&result_in_receiver); 3471 __ bind(&result_in_receiver);
3529 } else { 3472 } else {
3530 Label result_ok; 3473 Label result_ok;
3531 __ b(&result_ok); 3474 __ b(&result_ok);
3532 __ bind(&result_in_receiver); 3475 __ bind(&result_in_receiver);
3533 __ mov(result, receiver); 3476 __ mov(result, receiver);
3534 __ bind(&result_ok); 3477 __ bind(&result_ok);
3535 } 3478 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
3610 Register result = ToRegister(instr->result()); 3553 Register result = ToRegister(instr->result());
3611 if (info()->IsOptimizing()) { 3554 if (info()->IsOptimizing()) {
3612 __ ldr(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3555 __ ldr(result, MemOperand(fp, StandardFrameConstants::kContextOffset));
3613 } else { 3556 } else {
3614 // If there is no frame, the context must be in cp. 3557 // If there is no frame, the context must be in cp.
3615 ASSERT(result.is(cp)); 3558 ASSERT(result.is(cp));
3616 } 3559 }
3617 } 3560 }
3618 3561
3619 3562
3620 void LCodeGen::DoOuterContext(LOuterContext* instr) {
3621 Register context = ToRegister(instr->context());
3622 Register result = ToRegister(instr->result());
3623 __ ldr(result,
3624 MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
3625 }
3626
3627
3628 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3563 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
3629 ASSERT(ToRegister(instr->context()).is(cp)); 3564 ASSERT(ToRegister(instr->context()).is(cp));
3630 __ push(cp); // The context is the first argument. 3565 __ push(cp); // The context is the first argument.
3631 __ Move(scratch0(), instr->hydrogen()->pairs()); 3566 __ Move(scratch0(), instr->hydrogen()->pairs());
3632 __ push(scratch0()); 3567 __ push(scratch0());
3633 __ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); 3568 __ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags())));
3634 __ push(scratch0()); 3569 __ push(scratch0());
3635 CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3570 CallRuntime(Runtime::kDeclareGlobals, 3, instr);
3636 } 3571 }
3637 3572
3638 3573
3639 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
3640 Register context = ToRegister(instr->context());
3641 Register result = ToRegister(instr->result());
3642 __ ldr(result, ContextOperand(context, Context::GLOBAL_OBJECT_INDEX));
3643 }
3644
3645
3646 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
3647 Register global = ToRegister(instr->global_object());
3648 Register result = ToRegister(instr->result());
3649 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
3650 }
3651
3652
3653 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 3574 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
3654 int formal_parameter_count, 3575 int formal_parameter_count,
3655 int arity, 3576 int arity,
3656 LInstruction* instr, 3577 LInstruction* instr,
3657 R1State r1_state) { 3578 R1State r1_state) {
3658 bool dont_adapt_arguments = 3579 bool dont_adapt_arguments =
3659 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 3580 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3660 bool can_invoke_directly = 3581 bool can_invoke_directly =
3661 dont_adapt_arguments || formal_parameter_count == arity; 3582 dont_adapt_arguments || formal_parameter_count == arity;
3662 3583
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
3947 3868
3948 void LCodeGen::DoMathLog(LMathLog* instr) { 3869 void LCodeGen::DoMathLog(LMathLog* instr) {
3949 __ PrepareCallCFunction(0, 1, scratch0()); 3870 __ PrepareCallCFunction(0, 1, scratch0());
3950 __ MovToFloatParameter(ToDoubleRegister(instr->value())); 3871 __ MovToFloatParameter(ToDoubleRegister(instr->value()));
3951 __ CallCFunction(ExternalReference::math_log_double_function(isolate()), 3872 __ CallCFunction(ExternalReference::math_log_double_function(isolate()),
3952 0, 1); 3873 0, 1);
3953 __ MovFromFloatResult(ToDoubleRegister(instr->result())); 3874 __ MovFromFloatResult(ToDoubleRegister(instr->result()));
3954 } 3875 }
3955 3876
3956 3877
3878 void LCodeGen::DoMathClz32(LMathClz32* instr) {
3879 Register input = ToRegister(instr->value());
3880 Register result = ToRegister(instr->result());
3881 __ clz(result, input);
3882 }
3883
3884
3957 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3885 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3958 ASSERT(ToRegister(instr->context()).is(cp)); 3886 ASSERT(ToRegister(instr->context()).is(cp));
3959 ASSERT(ToRegister(instr->function()).is(r1)); 3887 ASSERT(ToRegister(instr->function()).is(r1));
3960 ASSERT(instr->HasPointerMap()); 3888 ASSERT(instr->HasPointerMap());
3961 3889
3962 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 3890 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3963 if (known_function.is_null()) { 3891 if (known_function.is_null()) {
3964 LPointerMap* pointers = instr->pointer_map(); 3892 LPointerMap* pointers = instr->pointer_map();
3965 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3893 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3966 ParameterCount count(instr->arity()); 3894 ParameterCount count(instr->arity());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4018 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 3946 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
4019 } 3947 }
4020 3948
4021 3949
4022 void LCodeGen::DoCallFunction(LCallFunction* instr) { 3950 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4023 ASSERT(ToRegister(instr->context()).is(cp)); 3951 ASSERT(ToRegister(instr->context()).is(cp));
4024 ASSERT(ToRegister(instr->function()).is(r1)); 3952 ASSERT(ToRegister(instr->function()).is(r1));
4025 ASSERT(ToRegister(instr->result()).is(r0)); 3953 ASSERT(ToRegister(instr->result()).is(r0));
4026 3954
4027 int arity = instr->arity(); 3955 int arity = instr->arity();
4028 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 3956 CallFunctionStub stub(arity, instr->hydrogen()->function_flags());
4029 if (instr->hydrogen()->IsTailCall()) { 3957 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4030 if (NeedsEagerFrame()) __ mov(sp, fp);
4031 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
4032 } else {
4033 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4034 }
4035 } 3958 }
4036 3959
4037 3960
4038 void LCodeGen::DoCallNew(LCallNew* instr) { 3961 void LCodeGen::DoCallNew(LCallNew* instr) {
4039 ASSERT(ToRegister(instr->context()).is(cp)); 3962 ASSERT(ToRegister(instr->context()).is(cp));
4040 ASSERT(ToRegister(instr->constructor()).is(r1)); 3963 ASSERT(ToRegister(instr->constructor()).is(r1));
4041 ASSERT(ToRegister(instr->result()).is(r0)); 3964 ASSERT(ToRegister(instr->result()).is(r0));
4042 3965
4043 __ mov(r0, Operand(instr->arity())); 3966 __ mov(r0, Operand(instr->arity()));
4044 // No cell in r2 for construct type feedback in optimized code 3967 // No cell in r2 for construct type feedback in optimized code
4045 Handle<Object> undefined_value(isolate()->factory()->undefined_value()); 3968 Handle<Object> undefined_value(isolate()->factory()->undefined_value());
4046 __ mov(r2, Operand(undefined_value)); 3969 __ mov(r2, Operand(undefined_value));
4047 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 3970 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
4048 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 3971 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4049 } 3972 }
4050 3973
4051 3974
4052 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { 3975 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
4053 ASSERT(ToRegister(instr->context()).is(cp)); 3976 ASSERT(ToRegister(instr->context()).is(cp));
4054 ASSERT(ToRegister(instr->constructor()).is(r1)); 3977 ASSERT(ToRegister(instr->constructor()).is(r1));
4055 ASSERT(ToRegister(instr->result()).is(r0)); 3978 ASSERT(ToRegister(instr->result()).is(r0));
4056 3979
4057 __ mov(r0, Operand(instr->arity())); 3980 __ mov(r0, Operand(instr->arity()));
4058 __ mov(r2, Operand(instr->hydrogen()->property_cell())); 3981 __ mov(r2, Operand(factory()->undefined_value()));
4059 ElementsKind kind = instr->hydrogen()->elements_kind(); 3982 ElementsKind kind = instr->hydrogen()->elements_kind();
4060 AllocationSiteOverrideMode override_mode = 3983 AllocationSiteOverrideMode override_mode =
4061 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 3984 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
4062 ? DISABLE_ALLOCATION_SITES 3985 ? DISABLE_ALLOCATION_SITES
4063 : DONT_OVERRIDE; 3986 : DONT_OVERRIDE;
4064 3987
4065 if (instr->arity() == 0) { 3988 if (instr->arity() == 0) {
4066 ArrayNoArgumentConstructorStub stub(kind, override_mode); 3989 ArrayNoArgumentConstructorStub stub(kind, override_mode);
4067 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 3990 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4068 } else if (instr->arity() == 1) { 3991 } else if (instr->arity() == 1) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
4128 int offset = access.offset(); 4051 int offset = access.offset();
4129 4052
4130 if (access.IsExternalMemory()) { 4053 if (access.IsExternalMemory()) {
4131 Register value = ToRegister(instr->value()); 4054 Register value = ToRegister(instr->value());
4132 MemOperand operand = MemOperand(object, offset); 4055 MemOperand operand = MemOperand(object, offset);
4133 __ Store(value, operand, representation); 4056 __ Store(value, operand, representation);
4134 return; 4057 return;
4135 } 4058 }
4136 4059
4137 Handle<Map> transition = instr->transition(); 4060 Handle<Map> transition = instr->transition();
4061 SmiCheck check_needed =
4062 instr->hydrogen()->value()->IsHeapObject()
4063 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4138 4064
4139 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 4065 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
4140 Register value = ToRegister(instr->value()); 4066 Register value = ToRegister(instr->value());
4141 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 4067 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4142 __ SmiTst(value); 4068 __ SmiTst(value);
4143 DeoptimizeIf(eq, instr->environment()); 4069 DeoptimizeIf(eq, instr->environment());
4070
4071 // We know that value is a smi now, so we can omit the check below.
4072 check_needed = OMIT_SMI_CHECK;
4144 } 4073 }
4145 } else if (FLAG_track_double_fields && representation.IsDouble()) { 4074 } else if (representation.IsDouble()) {
4146 ASSERT(transition.is_null()); 4075 ASSERT(transition.is_null());
4147 ASSERT(access.IsInobject()); 4076 ASSERT(access.IsInobject());
4148 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 4077 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
4149 DwVfpRegister value = ToDoubleRegister(instr->value()); 4078 DwVfpRegister value = ToDoubleRegister(instr->value());
4150 __ vstr(value, FieldMemOperand(object, offset)); 4079 __ vstr(value, FieldMemOperand(object, offset));
4151 return; 4080 return;
4152 } 4081 }
4153 4082
4154 if (!transition.is_null()) { 4083 if (!transition.is_null()) {
4155 __ mov(scratch, Operand(transition)); 4084 __ mov(scratch, Operand(transition));
4156 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 4085 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
4157 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { 4086 if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
4158 Register temp = ToRegister(instr->temp()); 4087 Register temp = ToRegister(instr->temp());
4159 // Update the write barrier for the map field. 4088 // Update the write barrier for the map field.
4160 __ RecordWriteField(object, 4089 __ RecordWriteField(object,
4161 HeapObject::kMapOffset, 4090 HeapObject::kMapOffset,
4162 scratch, 4091 scratch,
4163 temp, 4092 temp,
4164 GetLinkRegisterState(), 4093 GetLinkRegisterState(),
4165 kSaveFPRegs, 4094 kSaveFPRegs,
4166 OMIT_REMEMBERED_SET, 4095 OMIT_REMEMBERED_SET,
4167 OMIT_SMI_CHECK); 4096 OMIT_SMI_CHECK);
4168 } 4097 }
4169 } 4098 }
4170 4099
4171 // Do the store. 4100 // Do the store.
4172 Register value = ToRegister(instr->value()); 4101 Register value = ToRegister(instr->value());
4173 ASSERT(!object.is(value));
4174 SmiCheck check_needed =
4175 instr->hydrogen()->value()->IsHeapObject()
4176 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4177 if (access.IsInobject()) { 4102 if (access.IsInobject()) {
4178 MemOperand operand = FieldMemOperand(object, offset); 4103 MemOperand operand = FieldMemOperand(object, offset);
4179 __ Store(value, operand, representation); 4104 __ Store(value, operand, representation);
4180 if (instr->hydrogen()->NeedsWriteBarrier()) { 4105 if (instr->hydrogen()->NeedsWriteBarrier()) {
4181 // Update the write barrier for the object for in-object properties. 4106 // Update the write barrier for the object for in-object properties.
4182 __ RecordWriteField(object, 4107 __ RecordWriteField(object,
4183 offset, 4108 offset,
4184 value, 4109 value,
4185 scratch, 4110 scratch,
4186 GetLinkRegisterState(), 4111 GetLinkRegisterState(),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
4267 } else { 4192 } else {
4268 key = ToRegister(instr->key()); 4193 key = ToRegister(instr->key());
4269 } 4194 }
4270 int element_size_shift = ElementsKindToShiftSize(elements_kind); 4195 int element_size_shift = ElementsKindToShiftSize(elements_kind);
4271 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 4196 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
4272 ? (element_size_shift - kSmiTagSize) : element_size_shift; 4197 ? (element_size_shift - kSmiTagSize) : element_size_shift;
4273 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind) 4198 int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
4274 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 4199 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
4275 : 0; 4200 : 0;
4276 4201
4277 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4202 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
4278 elements_kind == FLOAT32_ELEMENTS || 4203 elements_kind == FLOAT32_ELEMENTS ||
4279 elements_kind == EXTERNAL_DOUBLE_ELEMENTS || 4204 elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
4280 elements_kind == FLOAT64_ELEMENTS) { 4205 elements_kind == FLOAT64_ELEMENTS) {
4281 int base_offset = 4206 int base_offset =
4282 (instr->additional_index() << element_size_shift) + additional_offset; 4207 (instr->additional_index() << element_size_shift) + additional_offset;
4283 Register address = scratch0(); 4208 Register address = scratch0();
4284 DwVfpRegister value(ToDoubleRegister(instr->value())); 4209 DwVfpRegister value(ToDoubleRegister(instr->value()));
4285 if (key_is_constant) { 4210 if (key_is_constant) {
4286 if (constant_key != 0) { 4211 if (constant_key != 0) {
4287 __ add(address, external_pointer, 4212 __ add(address, external_pointer,
4288 Operand(constant_key << element_size_shift)); 4213 Operand(constant_key << element_size_shift));
4289 } else { 4214 } else {
4290 address = external_pointer; 4215 address = external_pointer;
4291 } 4216 }
4292 } else { 4217 } else {
4293 __ add(address, external_pointer, Operand(key, LSL, shift_size)); 4218 __ add(address, external_pointer, Operand(key, LSL, shift_size));
4294 } 4219 }
4295 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 4220 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
4296 elements_kind == FLOAT32_ELEMENTS) { 4221 elements_kind == FLOAT32_ELEMENTS) {
4297 __ vcvt_f32_f64(double_scratch0().low(), value); 4222 __ vcvt_f32_f64(double_scratch0().low(), value);
4298 __ vstr(double_scratch0().low(), address, base_offset); 4223 __ vstr(double_scratch0().low(), address, base_offset);
4299 } else { // Storing doubles, not floats. 4224 } else { // Storing doubles, not floats.
4300 __ vstr(value, address, base_offset); 4225 __ vstr(value, address, base_offset);
4301 } 4226 }
4302 } else { 4227 } else {
4303 Register value(ToRegister(instr->value())); 4228 Register value(ToRegister(instr->value()));
4304 MemOperand mem_operand = PrepareKeyedOperand( 4229 MemOperand mem_operand = PrepareKeyedOperand(
4305 key, external_pointer, key_is_constant, constant_key, 4230 key, external_pointer, key_is_constant, constant_key,
4306 element_size_shift, shift_size, 4231 element_size_shift, shift_size,
4307 instr->additional_index(), additional_offset); 4232 instr->additional_index(), additional_offset);
4308 switch (elements_kind) { 4233 switch (elements_kind) {
4309 case EXTERNAL_PIXEL_ELEMENTS: 4234 case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
4310 case EXTERNAL_BYTE_ELEMENTS: 4235 case EXTERNAL_INT8_ELEMENTS:
4311 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4236 case EXTERNAL_UINT8_ELEMENTS:
4312 case UINT8_ELEMENTS: 4237 case UINT8_ELEMENTS:
4313 case UINT8_CLAMPED_ELEMENTS: 4238 case UINT8_CLAMPED_ELEMENTS:
4314 case INT8_ELEMENTS: 4239 case INT8_ELEMENTS:
4315 __ strb(value, mem_operand); 4240 __ strb(value, mem_operand);
4316 break; 4241 break;
4317 case EXTERNAL_SHORT_ELEMENTS: 4242 case EXTERNAL_INT16_ELEMENTS:
4318 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4243 case EXTERNAL_UINT16_ELEMENTS:
4319 case INT16_ELEMENTS: 4244 case INT16_ELEMENTS:
4320 case UINT16_ELEMENTS: 4245 case UINT16_ELEMENTS:
4321 __ strh(value, mem_operand); 4246 __ strh(value, mem_operand);
4322 break; 4247 break;
4323 case EXTERNAL_INT_ELEMENTS: 4248 case EXTERNAL_INT32_ELEMENTS:
4324 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4249 case EXTERNAL_UINT32_ELEMENTS:
4325 case INT32_ELEMENTS: 4250 case INT32_ELEMENTS:
4326 case UINT32_ELEMENTS: 4251 case UINT32_ELEMENTS:
4327 __ str(value, mem_operand); 4252 __ str(value, mem_operand);
4328 break; 4253 break;
4329 case FLOAT32_ELEMENTS: 4254 case FLOAT32_ELEMENTS:
4330 case FLOAT64_ELEMENTS: 4255 case FLOAT64_ELEMENTS:
4331 case EXTERNAL_FLOAT_ELEMENTS: 4256 case EXTERNAL_FLOAT32_ELEMENTS:
4332 case EXTERNAL_DOUBLE_ELEMENTS: 4257 case EXTERNAL_FLOAT64_ELEMENTS:
4333 case FAST_DOUBLE_ELEMENTS: 4258 case FAST_DOUBLE_ELEMENTS:
4334 case FAST_ELEMENTS: 4259 case FAST_ELEMENTS:
4335 case FAST_SMI_ELEMENTS: 4260 case FAST_SMI_ELEMENTS:
4336 case FAST_HOLEY_DOUBLE_ELEMENTS: 4261 case FAST_HOLEY_DOUBLE_ELEMENTS:
4337 case FAST_HOLEY_ELEMENTS: 4262 case FAST_HOLEY_ELEMENTS:
4338 case FAST_HOLEY_SMI_ELEMENTS: 4263 case FAST_HOLEY_SMI_ELEMENTS:
4339 case DICTIONARY_ELEMENTS: 4264 case DICTIONARY_ELEMENTS:
4340 case NON_STRICT_ARGUMENTS_ELEMENTS: 4265 case NON_STRICT_ARGUMENTS_ELEMENTS:
4341 UNREACHABLE(); 4266 UNREACHABLE();
4342 break; 4267 break;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
4501 Register temp = ToRegister(instr->temp()); 4426 Register temp = ToRegister(instr->temp());
4502 Label no_memento_found; 4427 Label no_memento_found;
4503 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); 4428 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
4504 DeoptimizeIf(eq, instr->environment()); 4429 DeoptimizeIf(eq, instr->environment());
4505 __ bind(&no_memento_found); 4430 __ bind(&no_memento_found);
4506 } 4431 }
4507 4432
4508 4433
4509 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4434 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4510 ASSERT(ToRegister(instr->context()).is(cp)); 4435 ASSERT(ToRegister(instr->context()).is(cp));
4511 if (FLAG_new_string_add) { 4436 ASSERT(ToRegister(instr->left()).is(r1));
4512 ASSERT(ToRegister(instr->left()).is(r1)); 4437 ASSERT(ToRegister(instr->right()).is(r0));
4513 ASSERT(ToRegister(instr->right()).is(r0)); 4438 StringAddStub stub(instr->hydrogen()->flags(),
4514 NewStringAddStub stub(instr->hydrogen()->flags(), 4439 instr->hydrogen()->pretenure_flag());
4515 isolate()->heap()->GetPretenureMode()); 4440 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4516 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4517 } else {
4518 __ push(ToRegister(instr->left()));
4519 __ push(ToRegister(instr->right()));
4520 StringAddStub stub(instr->hydrogen()->flags());
4521 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4522 }
4523 } 4441 }
4524 4442
4525 4443
4526 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 4444 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4527 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { 4445 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode {
4528 public: 4446 public:
4529 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 4447 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4530 : LDeferredCode(codegen), instr_(instr) { } 4448 : LDeferredCode(codegen), instr_(instr) { }
4531 virtual void Generate() V8_OVERRIDE { 4449 virtual void Generate() V8_OVERRIDE {
4532 codegen()->DoDeferredStringCharCodeAt(instr_); 4450 codegen()->DoDeferredStringCharCodeAt(instr_);
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
5334 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5252 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation());
5335 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5253 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5336 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); 5254 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
5337 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5255 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
5338 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); 5256 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
5339 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); 5257 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE);
5340 } 5258 }
5341 5259
5342 if (instr->size()->IsConstantOperand()) { 5260 if (instr->size()->IsConstantOperand()) {
5343 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5261 int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
5344 __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags); 5262 if (size <= Page::kMaxRegularHeapObjectSize) {
5263 __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
5264 } else {
5265 __ jmp(deferred->entry());
5266 }
5345 } else { 5267 } else {
5346 Register size = ToRegister(instr->size()); 5268 Register size = ToRegister(instr->size());
5347 __ Allocate(size, 5269 __ Allocate(size,
5348 result, 5270 result,
5349 scratch, 5271 scratch,
5350 scratch2, 5272 scratch2,
5351 deferred->entry(), 5273 deferred->entry(),
5352 flags); 5274 flags);
5353 } 5275 }
5354 5276
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
5831 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5753 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5832 __ ldr(result, FieldMemOperand(scratch, 5754 __ ldr(result, FieldMemOperand(scratch,
5833 FixedArray::kHeaderSize - kPointerSize)); 5755 FixedArray::kHeaderSize - kPointerSize));
5834 __ bind(&done); 5756 __ bind(&done);
5835 } 5757 }
5836 5758
5837 5759
5838 #undef __ 5760 #undef __
5839 5761
5840 } } // namespace v8::internal 5762 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698