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

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

Issue 6815010: Merge r7516, r7541 into 3.1 branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.1/
Patch Set: Created 9 years, 8 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-codegen-arm.h ('k') | src/deoptimizer.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 translation->StoreLiteral(src_index); 458 translation->StoreLiteral(src_index);
459 } else { 459 } else {
460 UNREACHABLE(); 460 UNREACHABLE();
461 } 461 }
462 } 462 }
463 463
464 464
465 void LCodeGen::CallCode(Handle<Code> code, 465 void LCodeGen::CallCode(Handle<Code> code,
466 RelocInfo::Mode mode, 466 RelocInfo::Mode mode,
467 LInstruction* instr) { 467 LInstruction* instr) {
468 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
469 }
470
471
472 void LCodeGen::CallCodeGeneric(Handle<Code> code,
473 RelocInfo::Mode mode,
474 LInstruction* instr,
475 SafepointMode safepoint_mode) {
468 ASSERT(instr != NULL); 476 ASSERT(instr != NULL);
469 LPointerMap* pointers = instr->pointer_map(); 477 LPointerMap* pointers = instr->pointer_map();
470 RecordPosition(pointers->position()); 478 RecordPosition(pointers->position());
471 __ Call(code, mode); 479 __ Call(code, mode);
472 RegisterLazyDeoptimization(instr); 480 RegisterLazyDeoptimization(instr, safepoint_mode);
473 } 481 }
474 482
475 483
476 void LCodeGen::CallRuntime(Runtime::Function* function, 484 void LCodeGen::CallRuntime(Runtime::Function* function,
477 int num_arguments, 485 int num_arguments,
478 LInstruction* instr) { 486 LInstruction* instr) {
479 ASSERT(instr != NULL); 487 ASSERT(instr != NULL);
480 LPointerMap* pointers = instr->pointer_map(); 488 LPointerMap* pointers = instr->pointer_map();
481 ASSERT(pointers != NULL); 489 ASSERT(pointers != NULL);
482 RecordPosition(pointers->position()); 490 RecordPosition(pointers->position());
483 491
484 __ CallRuntime(function, num_arguments); 492 __ CallRuntime(function, num_arguments);
485 RegisterLazyDeoptimization(instr); 493 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT);
486 } 494 }
487 495
488 496
489 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr) { 497 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
498 int argc,
499 LInstruction* instr) {
500 __ CallRuntimeSaveDoubles(id);
501 RecordSafepointWithRegisters(
502 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex);
503 }
504
505
506 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr,
507 SafepointMode safepoint_mode) {
490 // Create the environment to bailout to. If the call has side effects 508 // Create the environment to bailout to. If the call has side effects
491 // execution has to continue after the call otherwise execution can continue 509 // execution has to continue after the call otherwise execution can continue
492 // from a previous bailout point repeating the call. 510 // from a previous bailout point repeating the call.
493 LEnvironment* deoptimization_environment; 511 LEnvironment* deoptimization_environment;
494 if (instr->HasDeoptimizationEnvironment()) { 512 if (instr->HasDeoptimizationEnvironment()) {
495 deoptimization_environment = instr->deoptimization_environment(); 513 deoptimization_environment = instr->deoptimization_environment();
496 } else { 514 } else {
497 deoptimization_environment = instr->environment(); 515 deoptimization_environment = instr->environment();
498 } 516 }
499 517
500 RegisterEnvironmentForDeoptimization(deoptimization_environment); 518 RegisterEnvironmentForDeoptimization(deoptimization_environment);
501 RecordSafepoint(instr->pointer_map(), 519 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
502 deoptimization_environment->deoptimization_index()); 520 RecordSafepoint(instr->pointer_map(),
521 deoptimization_environment->deoptimization_index());
522 } else {
523 ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
524 RecordSafepointWithRegisters(
525 instr->pointer_map(),
526 0,
527 deoptimization_environment->deoptimization_index());
528 }
503 } 529 }
504 530
505 531
506 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) { 532 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) {
507 if (!environment->HasBeenRegistered()) { 533 if (!environment->HasBeenRegistered()) {
508 // Physical stack frame layout: 534 // Physical stack frame layout:
509 // -x ............. -4 0 ..................................... y 535 // -x ............. -4 0 ..................................... y
510 // [incoming arguments] [spill slots] [pushed outgoing arguments] 536 // [incoming arguments] [spill slots] [pushed outgoing arguments]
511 537
512 // Layout of the environment: 538 // Layout of the environment:
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 650
625 inlined_function_count_ = deoptimization_literals_.length(); 651 inlined_function_count_ = deoptimization_literals_.length();
626 } 652 }
627 653
628 654
629 void LCodeGen::RecordSafepoint( 655 void LCodeGen::RecordSafepoint(
630 LPointerMap* pointers, 656 LPointerMap* pointers,
631 Safepoint::Kind kind, 657 Safepoint::Kind kind,
632 int arguments, 658 int arguments,
633 int deoptimization_index) { 659 int deoptimization_index) {
660 ASSERT(expected_safepoint_kind_ == kind);
661
634 const ZoneList<LOperand*>* operands = pointers->operands(); 662 const ZoneList<LOperand*>* operands = pointers->operands();
635 Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 663 Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
636 kind, arguments, deoptimization_index); 664 kind, arguments, deoptimization_index);
637 for (int i = 0; i < operands->length(); i++) { 665 for (int i = 0; i < operands->length(); i++) {
638 LOperand* pointer = operands->at(i); 666 LOperand* pointer = operands->at(i);
639 if (pointer->IsStackSlot()) { 667 if (pointer->IsStackSlot()) {
640 safepoint.DefinePointerSlot(pointer->index()); 668 safepoint.DefinePointerSlot(pointer->index());
641 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 669 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
642 safepoint.DefinePointerRegister(ToRegister(pointer)); 670 safepoint.DefinePointerRegister(ToRegister(pointer));
643 } 671 }
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 __ bind(&done); 972 __ bind(&done);
945 } 973 }
946 974
947 975
948 template<int T> 976 template<int T>
949 void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr, 977 void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
950 Token::Value op) { 978 Token::Value op) {
951 Register left = ToRegister(instr->InputAt(0)); 979 Register left = ToRegister(instr->InputAt(0));
952 Register right = ToRegister(instr->InputAt(1)); 980 Register right = ToRegister(instr->InputAt(1));
953 981
954 __ PushSafepointRegistersAndDoubles(); 982 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles);
955 // Move left to r1 and right to r0 for the stub call. 983 // Move left to r1 and right to r0 for the stub call.
956 if (left.is(r1)) { 984 if (left.is(r1)) {
957 __ Move(r0, right); 985 __ Move(r0, right);
958 } else if (left.is(r0) && right.is(r1)) { 986 } else if (left.is(r0) && right.is(r1)) {
959 __ Swap(r0, r1, r2); 987 __ Swap(r0, r1, r2);
960 } else if (left.is(r0)) { 988 } else if (left.is(r0)) {
961 ASSERT(!right.is(r1)); 989 ASSERT(!right.is(r1));
962 __ mov(r1, r0); 990 __ mov(r1, r0);
963 __ mov(r0, right); 991 __ mov(r0, right);
964 } else { 992 } else {
965 ASSERT(!left.is(r0) && !right.is(r0)); 993 ASSERT(!left.is(r0) && !right.is(r0));
966 __ mov(r0, right); 994 __ mov(r0, right);
967 __ mov(r1, left); 995 __ mov(r1, left);
968 } 996 }
969 TypeRecordingBinaryOpStub stub(op, OVERWRITE_LEFT); 997 TypeRecordingBinaryOpStub stub(op, OVERWRITE_LEFT);
970 __ CallStub(&stub); 998 __ CallStub(&stub);
971 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), 999 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
972 0, 1000 0,
973 Safepoint::kNoDeoptimizationIndex); 1001 Safepoint::kNoDeoptimizationIndex);
974 // Overwrite the stored value of r0 with the result of the stub. 1002 // Overwrite the stored value of r0 with the result of the stub.
975 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); 1003 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
976 __ PopSafepointRegistersAndDoubles();
977 } 1004 }
978 1005
979 1006
980 void LCodeGen::DoMulI(LMulI* instr) { 1007 void LCodeGen::DoMulI(LMulI* instr) {
981 Register scratch = scratch0(); 1008 Register scratch = scratch0();
982 Register left = ToRegister(instr->InputAt(0)); 1009 Register left = ToRegister(instr->InputAt(0));
983 Register right = EmitLoadRegister(instr->InputAt(1), scratch); 1010 Register right = EmitLoadRegister(instr->InputAt(1), scratch);
984 1011
985 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && 1012 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) &&
986 !instr->InputAt(1)->IsConstantOperand()) { 1013 !instr->InputAt(1)->IsConstantOperand()) {
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 __ jmp(deferred_stack_check->entry()); 1389 __ jmp(deferred_stack_check->entry());
1363 deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block)); 1390 deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block));
1364 } else { 1391 } else {
1365 __ jmp(chunk_->GetAssemblyLabel(block)); 1392 __ jmp(chunk_->GetAssemblyLabel(block));
1366 } 1393 }
1367 } 1394 }
1368 } 1395 }
1369 1396
1370 1397
1371 void LCodeGen::DoDeferredStackCheck(LGoto* instr) { 1398 void LCodeGen::DoDeferredStackCheck(LGoto* instr) {
1372 __ PushSafepointRegisters(); 1399 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
1373 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 1400 CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr);
1374 RecordSafepointWithRegisters(
1375 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
1376 __ PopSafepointRegisters();
1377 } 1401 }
1378 1402
1379 1403
1380 void LCodeGen::DoGoto(LGoto* instr) { 1404 void LCodeGen::DoGoto(LGoto* instr) {
1381 class DeferredStackCheck: public LDeferredCode { 1405 class DeferredStackCheck: public LDeferredCode {
1382 public: 1406 public:
1383 DeferredStackCheck(LCodeGen* codegen, LGoto* instr) 1407 DeferredStackCheck(LCodeGen* codegen, LGoto* instr)
1384 : LDeferredCode(codegen), instr_(instr) { } 1408 : LDeferredCode(codegen), instr_(instr) { }
1385 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 1409 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
1386 private: 1410 private:
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 1989
1966 InstanceofStub::Flags flags = InstanceofStub::kNoFlags; 1990 InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
1967 flags = static_cast<InstanceofStub::Flags>( 1991 flags = static_cast<InstanceofStub::Flags>(
1968 flags | InstanceofStub::kArgsInRegisters); 1992 flags | InstanceofStub::kArgsInRegisters);
1969 flags = static_cast<InstanceofStub::Flags>( 1993 flags = static_cast<InstanceofStub::Flags>(
1970 flags | InstanceofStub::kCallSiteInlineCheck); 1994 flags | InstanceofStub::kCallSiteInlineCheck);
1971 flags = static_cast<InstanceofStub::Flags>( 1995 flags = static_cast<InstanceofStub::Flags>(
1972 flags | InstanceofStub::kReturnTrueFalseObject); 1996 flags | InstanceofStub::kReturnTrueFalseObject);
1973 InstanceofStub stub(flags); 1997 InstanceofStub stub(flags);
1974 1998
1975 __ PushSafepointRegisters(); 1999 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
1976 2000
1977 // Get the temp register reserved by the instruction. This needs to be r4 as 2001 // Get the temp register reserved by the instruction. This needs to be r4 as
1978 // its slot of the pushing of safepoint registers is used to communicate the 2002 // its slot of the pushing of safepoint registers is used to communicate the
1979 // offset to the location of the map check. 2003 // offset to the location of the map check.
1980 Register temp = ToRegister(instr->TempAt(0)); 2004 Register temp = ToRegister(instr->TempAt(0));
1981 ASSERT(temp.is(r4)); 2005 ASSERT(temp.is(r4));
1982 __ mov(InstanceofStub::right(), Operand(instr->function())); 2006 __ mov(InstanceofStub::right(), Operand(instr->function()));
1983 static const int kAdditionalDelta = 4; 2007 static const int kAdditionalDelta = 4;
1984 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; 2008 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
1985 Label before_push_delta; 2009 Label before_push_delta;
1986 __ bind(&before_push_delta); 2010 __ bind(&before_push_delta);
1987 __ BlockConstPoolFor(kAdditionalDelta); 2011 __ BlockConstPoolFor(kAdditionalDelta);
1988 __ mov(temp, Operand(delta * kPointerSize)); 2012 __ mov(temp, Operand(delta * kPointerSize));
1989 __ StoreToSafepointRegisterSlot(temp, temp); 2013 __ StoreToSafepointRegisterSlot(temp, temp);
1990 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2014 CallCodeGeneric(stub.GetCode(),
2015 RelocInfo::CODE_TARGET,
2016 instr,
2017 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
1991 // Put the result value into the result register slot and 2018 // Put the result value into the result register slot and
1992 // restore all registers. 2019 // restore all registers.
1993 __ StoreToSafepointRegisterSlot(result, result); 2020 __ StoreToSafepointRegisterSlot(result, result);
1994
1995 __ PopSafepointRegisters();
1996 } 2021 }
1997 2022
1998 2023
1999 static Condition ComputeCompareCondition(Token::Value op) { 2024 static Condition ComputeCompareCondition(Token::Value op) {
2000 switch (op) { 2025 switch (op) {
2001 case Token::EQ_STRICT: 2026 case Token::EQ_STRICT:
2002 case Token::EQ: 2027 case Token::EQ:
2003 return eq; 2028 return eq;
2004 case Token::LT: 2029 case Token::LT:
2005 return lt; 2030 return lt;
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
2449 } 2474 }
2450 2475
2451 LPointerMap* pointers = instr->pointer_map(); 2476 LPointerMap* pointers = instr->pointer_map();
2452 RecordPosition(pointers->position()); 2477 RecordPosition(pointers->position());
2453 2478
2454 // Invoke function. 2479 // Invoke function.
2455 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 2480 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
2456 __ Call(ip); 2481 __ Call(ip);
2457 2482
2458 // Setup deoptimization. 2483 // Setup deoptimization.
2459 RegisterLazyDeoptimization(instr); 2484 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT);
2460 2485
2461 // Restore context. 2486 // Restore context.
2462 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2487 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2463 } 2488 }
2464 2489
2465 2490
2466 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2491 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2467 ASSERT(ToRegister(instr->result()).is(r0)); 2492 ASSERT(ToRegister(instr->result()).is(r0));
2468 __ mov(r1, Operand(instr->function())); 2493 __ mov(r1, Operand(instr->function()));
2469 CallKnownFunction(instr->function(), instr->arity(), instr); 2494 CallKnownFunction(instr->function(), instr->arity(), instr);
(...skipping 17 matching lines...) Expand all
2487 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 2512 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2488 // Check the sign of the argument. If the argument is positive, just 2513 // Check the sign of the argument. If the argument is positive, just
2489 // return it. We do not need to patch the stack since |input| and 2514 // return it. We do not need to patch the stack since |input| and
2490 // |result| are the same register and |input| would be restored 2515 // |result| are the same register and |input| would be restored
2491 // unchanged by popping safepoint registers. 2516 // unchanged by popping safepoint registers.
2492 __ tst(exponent, Operand(HeapNumber::kSignMask)); 2517 __ tst(exponent, Operand(HeapNumber::kSignMask));
2493 __ b(eq, &done); 2518 __ b(eq, &done);
2494 2519
2495 // Input is negative. Reverse its sign. 2520 // Input is negative. Reverse its sign.
2496 // Preserve the value of all registers. 2521 // Preserve the value of all registers.
2497 __ PushSafepointRegisters(); 2522 {
2523 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2498 2524
2499 // Registers were saved at the safepoint, so we can use 2525 // Registers were saved at the safepoint, so we can use
2500 // many scratch registers. 2526 // many scratch registers.
2501 Register tmp1 = input.is(r1) ? r0 : r1; 2527 Register tmp1 = input.is(r1) ? r0 : r1;
2502 Register tmp2 = input.is(r2) ? r0 : r2; 2528 Register tmp2 = input.is(r2) ? r0 : r2;
2503 Register tmp3 = input.is(r3) ? r0 : r3; 2529 Register tmp3 = input.is(r3) ? r0 : r3;
2504 Register tmp4 = input.is(r4) ? r0 : r4; 2530 Register tmp4 = input.is(r4) ? r0 : r4;
2505 2531
2506 // exponent: floating point exponent value. 2532 // exponent: floating point exponent value.
2507 2533
2508 Label allocated, slow; 2534 Label allocated, slow;
2509 __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex); 2535 __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex);
2510 __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow); 2536 __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow);
2511 __ b(&allocated); 2537 __ b(&allocated);
2512 2538
2513 // Slow case: Call the runtime system to do the number allocation. 2539 // Slow case: Call the runtime system to do the number allocation.
2514 __ bind(&slow); 2540 __ bind(&slow);
2515 2541
2516 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 2542 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
2517 RecordSafepointWithRegisters( 2543 // Set the pointer to the new heap number in tmp.
2518 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); 2544 if (!tmp1.is(r0)) __ mov(tmp1, Operand(r0));
2519 // Set the pointer to the new heap number in tmp. 2545 // Restore input_reg after call to runtime.
2520 if (!tmp1.is(r0)) __ mov(tmp1, Operand(r0)); 2546 __ LoadFromSafepointRegisterSlot(input, input);
2521 // Restore input_reg after call to runtime. 2547 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2522 __ LoadFromSafepointRegisterSlot(input, input);
2523 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
2524 2548
2525 __ bind(&allocated); 2549 __ bind(&allocated);
2526 // exponent: floating point exponent value. 2550 // exponent: floating point exponent value.
2527 // tmp1: allocated heap number. 2551 // tmp1: allocated heap number.
2528 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask)); 2552 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask));
2529 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); 2553 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset));
2530 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); 2554 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
2531 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 2555 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
2532 2556
2533 __ StoreToSafepointRegisterSlot(tmp1, input); 2557 __ StoreToSafepointRegisterSlot(tmp1, input);
2534 __ PopSafepointRegisters(); 2558 }
2535 2559
2536 __ bind(&done); 2560 __ bind(&done);
2537 } 2561 }
2538 2562
2539 2563
2540 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2564 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2541 Register input = ToRegister(instr->InputAt(0)); 2565 Register input = ToRegister(instr->InputAt(0));
2542 __ cmp(input, Operand(0)); 2566 __ cmp(input, Operand(0));
2543 // We can make rsb conditional because the previous cmp instruction 2567 // We can make rsb conditional because the previous cmp instruction
2544 // will clear the V (overflow) flag and rsb won't set this flag 2568 // will clear the V (overflow) flag and rsb won't set this flag
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
2986 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 3010 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
2987 Register string = ToRegister(instr->string()); 3011 Register string = ToRegister(instr->string());
2988 Register result = ToRegister(instr->result()); 3012 Register result = ToRegister(instr->result());
2989 Register scratch = scratch0(); 3013 Register scratch = scratch0();
2990 3014
2991 // TODO(3095996): Get rid of this. For now, we need to make the 3015 // TODO(3095996): Get rid of this. For now, we need to make the
2992 // result register contain a valid pointer because it is already 3016 // result register contain a valid pointer because it is already
2993 // contained in the register pointer map. 3017 // contained in the register pointer map.
2994 __ mov(result, Operand(0)); 3018 __ mov(result, Operand(0));
2995 3019
2996 __ PushSafepointRegisters(); 3020 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2997 __ push(string); 3021 __ push(string);
2998 // Push the index as a smi. This is safe because of the checks in 3022 // Push the index as a smi. This is safe because of the checks in
2999 // DoStringCharCodeAt above. 3023 // DoStringCharCodeAt above.
3000 if (instr->index()->IsConstantOperand()) { 3024 if (instr->index()->IsConstantOperand()) {
3001 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3025 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3002 __ mov(scratch, Operand(Smi::FromInt(const_index))); 3026 __ mov(scratch, Operand(Smi::FromInt(const_index)));
3003 __ push(scratch); 3027 __ push(scratch);
3004 } else { 3028 } else {
3005 Register index = ToRegister(instr->index()); 3029 Register index = ToRegister(instr->index());
3006 __ SmiTag(index); 3030 __ SmiTag(index);
3007 __ push(index); 3031 __ push(index);
3008 } 3032 }
3009 __ CallRuntimeSaveDoubles(Runtime::kStringCharCodeAt); 3033 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
3010 RecordSafepointWithRegisters(
3011 instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex);
3012 if (FLAG_debug_code) { 3034 if (FLAG_debug_code) {
3013 __ AbortIfNotSmi(r0); 3035 __ AbortIfNotSmi(r0);
3014 } 3036 }
3015 __ SmiUntag(r0); 3037 __ SmiUntag(r0);
3016 __ StoreToSafepointRegisterSlot(r0, result); 3038 __ StoreToSafepointRegisterSlot(r0, result);
3017 __ PopSafepointRegisters();
3018 } 3039 }
3019 3040
3020 3041
3021 void LCodeGen::DoStringLength(LStringLength* instr) { 3042 void LCodeGen::DoStringLength(LStringLength* instr) {
3022 Register string = ToRegister(instr->InputAt(0)); 3043 Register string = ToRegister(instr->InputAt(0));
3023 Register result = ToRegister(instr->result()); 3044 Register result = ToRegister(instr->result());
3024 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); 3045 __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
3025 } 3046 }
3026 3047
3027 3048
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3063 } 3084 }
3064 3085
3065 3086
3066 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 3087 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
3067 Label slow; 3088 Label slow;
3068 Register reg = ToRegister(instr->InputAt(0)); 3089 Register reg = ToRegister(instr->InputAt(0));
3069 DoubleRegister dbl_scratch = d0; 3090 DoubleRegister dbl_scratch = d0;
3070 SwVfpRegister flt_scratch = s0; 3091 SwVfpRegister flt_scratch = s0;
3071 3092
3072 // Preserve the value of all registers. 3093 // Preserve the value of all registers.
3073 __ PushSafepointRegisters(); 3094 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3074 3095
3075 // There was overflow, so bits 30 and 31 of the original integer 3096 // There was overflow, so bits 30 and 31 of the original integer
3076 // disagree. Try to allocate a heap number in new space and store 3097 // disagree. Try to allocate a heap number in new space and store
3077 // the value in there. If that fails, call the runtime system. 3098 // the value in there. If that fails, call the runtime system.
3078 Label done; 3099 Label done;
3079 __ SmiUntag(reg); 3100 __ SmiUntag(reg);
3080 __ eor(reg, reg, Operand(0x80000000)); 3101 __ eor(reg, reg, Operand(0x80000000));
3081 __ vmov(flt_scratch, reg); 3102 __ vmov(flt_scratch, reg);
3082 __ vcvt_f64_s32(dbl_scratch, flt_scratch); 3103 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
3083 if (FLAG_inline_new) { 3104 if (FLAG_inline_new) {
3084 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 3105 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3085 __ AllocateHeapNumber(r5, r3, r4, r6, &slow); 3106 __ AllocateHeapNumber(r5, r3, r4, r6, &slow);
3086 if (!reg.is(r5)) __ mov(reg, r5); 3107 if (!reg.is(r5)) __ mov(reg, r5);
3087 __ b(&done); 3108 __ b(&done);
3088 } 3109 }
3089 3110
3090 // Slow case: Call the runtime system to do the number allocation. 3111 // Slow case: Call the runtime system to do the number allocation.
3091 __ bind(&slow); 3112 __ bind(&slow);
3092 3113
3093 // TODO(3095996): Put a valid pointer value in the stack slot where the result 3114 // TODO(3095996): Put a valid pointer value in the stack slot where the result
3094 // register is stored, as this register is in the pointer map, but contains an 3115 // register is stored, as this register is in the pointer map, but contains an
3095 // integer value. 3116 // integer value.
3096 __ mov(ip, Operand(0)); 3117 __ mov(ip, Operand(0));
3097 __ StoreToSafepointRegisterSlot(ip, reg); 3118 __ StoreToSafepointRegisterSlot(ip, reg);
3098 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 3119 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
3099 RecordSafepointWithRegisters(
3100 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
3101 if (!reg.is(r0)) __ mov(reg, r0); 3120 if (!reg.is(r0)) __ mov(reg, r0);
3102 3121
3103 // Done. Put the value in dbl_scratch into the value of the allocated heap 3122 // Done. Put the value in dbl_scratch into the value of the allocated heap
3104 // number. 3123 // number.
3105 __ bind(&done); 3124 __ bind(&done);
3106 __ sub(ip, reg, Operand(kHeapObjectTag)); 3125 __ sub(ip, reg, Operand(kHeapObjectTag));
3107 __ vstr(dbl_scratch, ip, HeapNumber::kValueOffset); 3126 __ vstr(dbl_scratch, ip, HeapNumber::kValueOffset);
3108 __ StoreToSafepointRegisterSlot(reg, reg); 3127 __ StoreToSafepointRegisterSlot(reg, reg);
3109 __ PopSafepointRegisters();
3110 } 3128 }
3111 3129
3112 3130
3113 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 3131 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
3114 class DeferredNumberTagD: public LDeferredCode { 3132 class DeferredNumberTagD: public LDeferredCode {
3115 public: 3133 public:
3116 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 3134 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
3117 : LDeferredCode(codegen), instr_(instr) { } 3135 : LDeferredCode(codegen), instr_(instr) { }
3118 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 3136 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
3119 private: 3137 private:
(...skipping 19 matching lines...) Expand all
3139 } 3157 }
3140 3158
3141 3159
3142 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 3160 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
3143 // TODO(3095996): Get rid of this. For now, we need to make the 3161 // TODO(3095996): Get rid of this. For now, we need to make the
3144 // result register contain a valid pointer because it is already 3162 // result register contain a valid pointer because it is already
3145 // contained in the register pointer map. 3163 // contained in the register pointer map.
3146 Register reg = ToRegister(instr->result()); 3164 Register reg = ToRegister(instr->result());
3147 __ mov(reg, Operand(0)); 3165 __ mov(reg, Operand(0));
3148 3166
3149 __ PushSafepointRegisters(); 3167 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
3150 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 3168 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
3151 RecordSafepointWithRegisters(
3152 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
3153 __ StoreToSafepointRegisterSlot(r0, reg); 3169 __ StoreToSafepointRegisterSlot(r0, reg);
3154 __ PopSafepointRegisters();
3155 } 3170 }
3156 3171
3157 3172
3158 void LCodeGen::DoSmiTag(LSmiTag* instr) { 3173 void LCodeGen::DoSmiTag(LSmiTag* instr) {
3159 LOperand* input = instr->InputAt(0); 3174 LOperand* input = instr->InputAt(0);
3160 ASSERT(input->IsRegister() && input->Equals(instr->result())); 3175 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3161 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 3176 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
3162 __ SmiTag(ToRegister(input)); 3177 __ SmiTag(ToRegister(input));
3163 } 3178 }
3164 3179
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
3814 ASSERT(!environment->HasBeenRegistered()); 3829 ASSERT(!environment->HasBeenRegistered());
3815 RegisterEnvironmentForDeoptimization(environment); 3830 RegisterEnvironmentForDeoptimization(environment);
3816 ASSERT(osr_pc_offset_ == -1); 3831 ASSERT(osr_pc_offset_ == -1);
3817 osr_pc_offset_ = masm()->pc_offset(); 3832 osr_pc_offset_ = masm()->pc_offset();
3818 } 3833 }
3819 3834
3820 3835
3821 #undef __ 3836 #undef __
3822 3837
3823 } } // namespace v8::internal 3838 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/deoptimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698