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

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

Issue 6793017: In LCodeGen::DoDeferredLInstanceOfKnownGlobal emit safepoint with registers for the call to stub. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: port to arm and x64 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
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 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 } else if (op->IsConstantOperand()) { 433 } else if (op->IsConstantOperand()) {
434 Handle<Object> literal = chunk()->LookupLiteral(LConstantOperand::cast(op)); 434 Handle<Object> literal = chunk()->LookupLiteral(LConstantOperand::cast(op));
435 int src_index = DefineDeoptimizationLiteral(literal); 435 int src_index = DefineDeoptimizationLiteral(literal);
436 translation->StoreLiteral(src_index); 436 translation->StoreLiteral(src_index);
437 } else { 437 } else {
438 UNREACHABLE(); 438 UNREACHABLE();
439 } 439 }
440 } 440 }
441 441
442 442
443 void LCodeGen::CallCode(Handle<Code> code, 443 void LCodeGen::CallCodeGeneric(Handle<Code> code,
444 RelocInfo::Mode mode, 444 RelocInfo::Mode mode,
445 LInstruction* instr) { 445 LInstruction* instr,
446 SafepointMode safepoint_mode,
447 int argc) {
446 ASSERT(instr != NULL); 448 ASSERT(instr != NULL);
447 LPointerMap* pointers = instr->pointer_map(); 449 LPointerMap* pointers = instr->pointer_map();
448 RecordPosition(pointers->position()); 450 RecordPosition(pointers->position());
449 __ call(code, mode); 451 __ call(code, mode);
450 RegisterLazyDeoptimization(instr); 452 RegisterLazyDeoptimization(instr, safepoint_mode, argc);
451 453
452 // Signal that we don't inline smi code before these stubs in the 454 // Signal that we don't inline smi code before these stubs in the
453 // optimizing code generator. 455 // optimizing code generator.
454 if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC || 456 if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC ||
455 code->kind() == Code::COMPARE_IC) { 457 code->kind() == Code::COMPARE_IC) {
456 __ nop(); 458 __ nop();
457 } 459 }
458 } 460 }
459 461
460 462
463 void LCodeGen::CallCode(Handle<Code> code,
464 RelocInfo::Mode mode,
465 LInstruction* instr) {
466 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, 0);
467 }
468
469
461 void LCodeGen::CallRuntime(const Runtime::Function* function, 470 void LCodeGen::CallRuntime(const Runtime::Function* function,
462 int num_arguments, 471 int num_arguments,
463 LInstruction* instr) { 472 LInstruction* instr) {
464 ASSERT(instr != NULL); 473 ASSERT(instr != NULL);
465 ASSERT(instr->HasPointerMap()); 474 ASSERT(instr->HasPointerMap());
466 LPointerMap* pointers = instr->pointer_map(); 475 LPointerMap* pointers = instr->pointer_map();
467 RecordPosition(pointers->position()); 476 RecordPosition(pointers->position());
468 477
469 __ CallRuntime(function, num_arguments); 478 __ CallRuntime(function, num_arguments);
470 RegisterLazyDeoptimization(instr); 479 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0);
471 } 480 }
472 481
473 482
474 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr) { 483 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
484 int argc,
485 LInstruction* instr) {
486 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
487 __ CallRuntimeSaveDoubles(id);
488 RecordSafepointWithRegisters(
489 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex);
490 }
491
492
493 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr,
494 SafepointMode safepoint_mode,
495 int argc) {
475 // Create the environment to bailout to. If the call has side effects 496 // Create the environment to bailout to. If the call has side effects
476 // execution has to continue after the call otherwise execution can continue 497 // execution has to continue after the call otherwise execution can continue
477 // from a previous bailout point repeating the call. 498 // from a previous bailout point repeating the call.
478 LEnvironment* deoptimization_environment; 499 LEnvironment* deoptimization_environment;
479 if (instr->HasDeoptimizationEnvironment()) { 500 if (instr->HasDeoptimizationEnvironment()) {
480 deoptimization_environment = instr->deoptimization_environment(); 501 deoptimization_environment = instr->deoptimization_environment();
481 } else { 502 } else {
482 deoptimization_environment = instr->environment(); 503 deoptimization_environment = instr->environment();
483 } 504 }
484 505
485 RegisterEnvironmentForDeoptimization(deoptimization_environment); 506 RegisterEnvironmentForDeoptimization(deoptimization_environment);
486 RecordSafepoint(instr->pointer_map(), 507 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
487 deoptimization_environment->deoptimization_index()); 508 ASSERT(argc == 0);
509 RecordSafepoint(instr->pointer_map(),
510 deoptimization_environment->deoptimization_index());
511 } else {
512 ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS);
513 RecordSafepointWithRegisters(
514 instr->pointer_map(),
515 argc,
516 deoptimization_environment->deoptimization_index());
517 }
488 } 518 }
489 519
490 520
491 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) { 521 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) {
492 if (!environment->HasBeenRegistered()) { 522 if (!environment->HasBeenRegistered()) {
493 // Physical stack frame layout: 523 // Physical stack frame layout:
494 // -x ............. -4 0 ..................................... y 524 // -x ............. -4 0 ..................................... y
495 // [incoming arguments] [spill slots] [pushed outgoing arguments] 525 // [incoming arguments] [spill slots] [pushed outgoing arguments]
496 526
497 // Layout of the environment: 527 // Layout of the environment:
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 628
599 inlined_function_count_ = deoptimization_literals_.length(); 629 inlined_function_count_ = deoptimization_literals_.length();
600 } 630 }
601 631
602 632
603 void LCodeGen::RecordSafepoint( 633 void LCodeGen::RecordSafepoint(
604 LPointerMap* pointers, 634 LPointerMap* pointers,
605 Safepoint::Kind kind, 635 Safepoint::Kind kind,
606 int arguments, 636 int arguments,
607 int deoptimization_index) { 637 int deoptimization_index) {
638 ASSERT(kind == expected_safepoint_kind_);
639
608 const ZoneList<LOperand*>* operands = pointers->operands(); 640 const ZoneList<LOperand*>* operands = pointers->operands();
609 641
610 Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 642 Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
611 kind, arguments, deoptimization_index); 643 kind, arguments, deoptimization_index);
612 for (int i = 0; i < operands->length(); i++) { 644 for (int i = 0; i < operands->length(); i++) {
613 LOperand* pointer = operands->at(i); 645 LOperand* pointer = operands->at(i);
614 if (pointer->IsStackSlot()) { 646 if (pointer->IsStackSlot()) {
615 safepoint.DefinePointerSlot(pointer->index()); 647 safepoint.DefinePointerSlot(pointer->index());
616 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 648 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
617 safepoint.DefinePointerRegister(ToRegister(pointer)); 649 safepoint.DefinePointerRegister(ToRegister(pointer));
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 __ jmp(deferred_stack_check->entry()); 1353 __ jmp(deferred_stack_check->entry());
1322 deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block)); 1354 deferred_stack_check->SetExit(chunk_->GetAssemblyLabel(block));
1323 } else { 1355 } else {
1324 __ jmp(chunk_->GetAssemblyLabel(block)); 1356 __ jmp(chunk_->GetAssemblyLabel(block));
1325 } 1357 }
1326 } 1358 }
1327 } 1359 }
1328 1360
1329 1361
1330 void LCodeGen::DoDeferredStackCheck(LGoto* instr) { 1362 void LCodeGen::DoDeferredStackCheck(LGoto* instr) {
1331 __ Pushad(); 1363 PushSafepointRegistersScope scope(this);
1332 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 1364 CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr);
1333 RecordSafepointWithRegisters(
1334 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
1335 __ Popad();
1336 } 1365 }
1337 1366
1338 1367
1339 void LCodeGen::DoGoto(LGoto* instr) { 1368 void LCodeGen::DoGoto(LGoto* instr) {
1340 class DeferredStackCheck: public LDeferredCode { 1369 class DeferredStackCheck: public LDeferredCode {
1341 public: 1370 public:
1342 DeferredStackCheck(LCodeGen* codegen, LGoto* instr) 1371 DeferredStackCheck(LCodeGen* codegen, LGoto* instr)
1343 : LDeferredCode(codegen), instr_(instr) { } 1372 : LDeferredCode(codegen), instr_(instr) { }
1344 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 1373 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
1345 private: 1374 private:
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
1930 __ bind(&false_result); 1959 __ bind(&false_result);
1931 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 1960 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
1932 1961
1933 __ bind(deferred->exit()); 1962 __ bind(deferred->exit());
1934 __ bind(&done); 1963 __ bind(&done);
1935 } 1964 }
1936 1965
1937 1966
1938 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 1967 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
1939 Label* map_check) { 1968 Label* map_check) {
1940 __ PushSafepointRegisters(); 1969 {
1941 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( 1970 PushSafepointRegistersScope scope(this);
1942 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); 1971 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
1943 InstanceofStub stub(flags); 1972 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck);
1973 InstanceofStub stub(flags);
1944 1974
1945 __ push(ToRegister(instr->InputAt(0))); 1975 __ push(ToRegister(instr->InputAt(0)));
1946 __ Push(instr->function()); 1976 __ Push(instr->function());
1947 Register temp = ToRegister(instr->TempAt(0)); 1977
1948 ASSERT(temp.is(rdi)); 1978 Register temp = ToRegister(instr->TempAt(0));
1949 static const int kAdditionalDelta = 16; 1979 static const int kAdditionalDelta = 13;
1950 int delta = 1980 int delta =
1951 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 1981 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
1952 __ movq(temp, Immediate(delta)); 1982 __ movq(temp, Immediate(delta));
1953 __ push(temp); 1983 __ push(temp);
1954 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1984
1955 __ movq(kScratchRegister, rax); 1985 //
fschneider 2011/04/07 11:28:30 Remove extra line.
1956 __ PopSafepointRegisters(); 1986 CallCodeGeneric(stub.GetCode(),
1987 RelocInfo::CODE_TARGET,
1988 instr,
1989 RECORD_SAFEPOINT_WITH_REGISTERS,
1990 2);
1991 ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check));
1992 __ movq(kScratchRegister, rax);
1993 }
1957 __ testq(kScratchRegister, kScratchRegister); 1994 __ testq(kScratchRegister, kScratchRegister);
1958 Label load_false; 1995 Label load_false;
1959 Label done; 1996 Label done;
1960 __ j(not_zero, &load_false); 1997 __ j(not_zero, &load_false);
1961 __ LoadRoot(rax, Heap::kTrueValueRootIndex); 1998 __ LoadRoot(rax, Heap::kTrueValueRootIndex);
1962 __ jmp(&done); 1999 __ jmp(&done);
1963 __ bind(&load_false); 2000 __ bind(&load_false);
1964 __ LoadRoot(rax, Heap::kFalseValueRootIndex); 2001 __ LoadRoot(rax, Heap::kFalseValueRootIndex);
1965 __ bind(&done); 2002 __ bind(&done);
1966 } 2003 }
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 RecordPosition(pointers->position()); 2565 RecordPosition(pointers->position());
2529 2566
2530 // Invoke function. 2567 // Invoke function.
2531 if (*function == *info()->closure()) { 2568 if (*function == *info()->closure()) {
2532 __ CallSelf(); 2569 __ CallSelf();
2533 } else { 2570 } else {
2534 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2571 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2535 } 2572 }
2536 2573
2537 // Setup deoptimization. 2574 // Setup deoptimization.
2538 RegisterLazyDeoptimization(instr); 2575 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0);
2539 2576
2540 // Restore context. 2577 // Restore context.
2541 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2578 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2542 } 2579 }
2543 2580
2544 2581
2545 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2582 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2546 ASSERT(ToRegister(instr->result()).is(rax)); 2583 ASSERT(ToRegister(instr->result()).is(rax));
2547 __ Move(rdi, instr->function()); 2584 __ Move(rdi, instr->function());
2548 CallKnownFunction(instr->function(), instr->arity(), instr); 2585 CallKnownFunction(instr->function(), instr->arity(), instr);
2549 } 2586 }
2550 2587
2551 2588
2552 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2589 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2553 Register input_reg = ToRegister(instr->InputAt(0)); 2590 Register input_reg = ToRegister(instr->InputAt(0));
2554 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 2591 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
2555 Heap::kHeapNumberMapRootIndex); 2592 Heap::kHeapNumberMapRootIndex);
2556 DeoptimizeIf(not_equal, instr->environment()); 2593 DeoptimizeIf(not_equal, instr->environment());
2557 2594
2558 Label done; 2595 Label done;
2559 Register tmp = input_reg.is(rax) ? rcx : rax; 2596 Register tmp = input_reg.is(rax) ? rcx : rax;
2560 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; 2597 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
2561 2598
2562 // Preserve the value of all registers. 2599 // Preserve the value of all registers.
2563 __ PushSafepointRegisters(); 2600 PushSafepointRegistersScope scope(this);
2564 2601
2565 Label negative; 2602 Label negative;
2566 __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 2603 __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset));
2567 // Check the sign of the argument. If the argument is positive, just 2604 // Check the sign of the argument. If the argument is positive, just
2568 // return it. We do not need to patch the stack since |input| and 2605 // return it. We do not need to patch the stack since |input| and
2569 // |result| are the same register and |input| will be restored 2606 // |result| are the same register and |input| will be restored
2570 // unchanged by popping safepoint registers. 2607 // unchanged by popping safepoint registers.
2571 __ testl(tmp, Immediate(HeapNumber::kSignMask)); 2608 __ testl(tmp, Immediate(HeapNumber::kSignMask));
2572 __ j(not_zero, &negative); 2609 __ j(not_zero, &negative);
2573 __ jmp(&done); 2610 __ jmp(&done);
2574 2611
2575 __ bind(&negative); 2612 __ bind(&negative);
2576 2613
2577 Label allocated, slow; 2614 Label allocated, slow;
2578 __ AllocateHeapNumber(tmp, tmp2, &slow); 2615 __ AllocateHeapNumber(tmp, tmp2, &slow);
2579 __ jmp(&allocated); 2616 __ jmp(&allocated);
2580 2617
2581 // Slow case: Call the runtime system to do the number allocation. 2618 // Slow case: Call the runtime system to do the number allocation.
2582 __ bind(&slow); 2619 __ bind(&slow);
2583 2620
2584 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 2621 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
2585 RecordSafepointWithRegisters(
2586 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
2587 // Set the pointer to the new heap number in tmp. 2622 // Set the pointer to the new heap number in tmp.
2588 if (!tmp.is(rax)) { 2623 if (!tmp.is(rax)) {
2589 __ movq(tmp, rax); 2624 __ movq(tmp, rax);
2590 } 2625 }
2591 2626
2592 // Restore input_reg after call to runtime. 2627 // Restore input_reg after call to runtime.
2593 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); 2628 __ LoadFromSafepointRegisterSlot(input_reg, input_reg);
2594 2629
2595 __ bind(&allocated); 2630 __ bind(&allocated);
2596 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); 2631 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
2597 __ shl(tmp2, Immediate(1)); 2632 __ shl(tmp2, Immediate(1));
2598 __ shr(tmp2, Immediate(1)); 2633 __ shr(tmp2, Immediate(1));
2599 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); 2634 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
2600 __ StoreToSafepointRegisterSlot(input_reg, tmp); 2635 __ StoreToSafepointRegisterSlot(input_reg, tmp);
2601 2636
2602 __ bind(&done); 2637 __ bind(&done);
2603 __ PopSafepointRegisters();
2604 } 2638 }
2605 2639
2606 2640
2607 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2641 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2608 Register input_reg = ToRegister(instr->InputAt(0)); 2642 Register input_reg = ToRegister(instr->InputAt(0));
2609 __ testl(input_reg, input_reg); 2643 __ testl(input_reg, input_reg);
2610 Label is_positive; 2644 Label is_positive;
2611 __ j(not_sign, &is_positive); 2645 __ j(not_sign, &is_positive);
2612 __ negl(input_reg); // Sets flags. 2646 __ negl(input_reg); // Sets flags.
2613 DeoptimizeIf(negative, instr->environment()); 2647 DeoptimizeIf(negative, instr->environment());
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
3152 3186
3153 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 3187 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
3154 Register string = ToRegister(instr->string()); 3188 Register string = ToRegister(instr->string());
3155 Register result = ToRegister(instr->result()); 3189 Register result = ToRegister(instr->result());
3156 3190
3157 // TODO(3095996): Get rid of this. For now, we need to make the 3191 // TODO(3095996): Get rid of this. For now, we need to make the
3158 // result register contain a valid pointer because it is already 3192 // result register contain a valid pointer because it is already
3159 // contained in the register pointer map. 3193 // contained in the register pointer map.
3160 __ Set(result, 0); 3194 __ Set(result, 0);
3161 3195
3162 __ PushSafepointRegisters(); 3196 PushSafepointRegistersScope scope(this);
3163 __ push(string); 3197 __ push(string);
3164 // Push the index as a smi. This is safe because of the checks in 3198 // Push the index as a smi. This is safe because of the checks in
3165 // DoStringCharCodeAt above. 3199 // DoStringCharCodeAt above.
3166 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 3200 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3167 if (instr->index()->IsConstantOperand()) { 3201 if (instr->index()->IsConstantOperand()) {
3168 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3202 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3169 __ Push(Smi::FromInt(const_index)); 3203 __ Push(Smi::FromInt(const_index));
3170 } else { 3204 } else {
3171 Register index = ToRegister(instr->index()); 3205 Register index = ToRegister(instr->index());
3172 __ Integer32ToSmi(index, index); 3206 __ Integer32ToSmi(index, index);
3173 __ push(index); 3207 __ push(index);
3174 } 3208 }
3175 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3209 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
3176 __ CallRuntimeSaveDoubles(Runtime::kStringCharCodeAt);
3177 RecordSafepointWithRegisters(
3178 instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex);
3179 if (FLAG_debug_code) { 3210 if (FLAG_debug_code) {
3180 __ AbortIfNotSmi(rax); 3211 __ AbortIfNotSmi(rax);
3181 } 3212 }
3182 __ SmiToInteger32(rax, rax); 3213 __ SmiToInteger32(rax, rax);
3183 __ StoreToSafepointRegisterSlot(result, rax); 3214 __ StoreToSafepointRegisterSlot(result, rax);
3184 __ PopSafepointRegisters();
3185 } 3215 }
3186 3216
3187 3217
3188 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 3218 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
3189 class DeferredStringCharFromCode: public LDeferredCode { 3219 class DeferredStringCharFromCode: public LDeferredCode {
3190 public: 3220 public:
3191 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 3221 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
3192 : LDeferredCode(codegen), instr_(instr) { } 3222 : LDeferredCode(codegen), instr_(instr) { }
3193 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } 3223 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
3194 private: 3224 private:
(...skipping 22 matching lines...) Expand all
3217 3247
3218 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { 3248 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
3219 Register char_code = ToRegister(instr->char_code()); 3249 Register char_code = ToRegister(instr->char_code());
3220 Register result = ToRegister(instr->result()); 3250 Register result = ToRegister(instr->result());
3221 3251
3222 // TODO(3095996): Get rid of this. For now, we need to make the 3252 // TODO(3095996): Get rid of this. For now, we need to make the
3223 // result register contain a valid pointer because it is already 3253 // result register contain a valid pointer because it is already
3224 // contained in the register pointer map. 3254 // contained in the register pointer map.
3225 __ Set(result, 0); 3255 __ Set(result, 0);
3226 3256
3227 __ PushSafepointRegisters(); 3257 PushSafepointRegistersScope scope(this);
3228 __ Integer32ToSmi(char_code, char_code); 3258 __ Integer32ToSmi(char_code, char_code);
3229 __ push(char_code); 3259 __ push(char_code);
3230 __ CallRuntimeSaveDoubles(Runtime::kCharFromCode); 3260 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr);
3231 RecordSafepointWithRegisters(
3232 instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex);
3233 __ StoreToSafepointRegisterSlot(result, rax); 3261 __ StoreToSafepointRegisterSlot(result, rax);
3234 __ PopSafepointRegisters();
3235 } 3262 }
3236 3263
3237 3264
3238 void LCodeGen::DoStringLength(LStringLength* instr) { 3265 void LCodeGen::DoStringLength(LStringLength* instr) {
3239 Register string = ToRegister(instr->string()); 3266 Register string = ToRegister(instr->string());
3240 Register result = ToRegister(instr->result()); 3267 Register result = ToRegister(instr->result());
3241 __ movq(result, FieldOperand(string, String::kLengthOffset)); 3268 __ movq(result, FieldOperand(string, String::kLengthOffset));
3242 } 3269 }
3243 3270
3244 3271
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3289 } 3316 }
3290 3317
3291 3318
3292 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 3319 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
3293 // TODO(3095996): Get rid of this. For now, we need to make the 3320 // TODO(3095996): Get rid of this. For now, we need to make the
3294 // result register contain a valid pointer because it is already 3321 // result register contain a valid pointer because it is already
3295 // contained in the register pointer map. 3322 // contained in the register pointer map.
3296 Register reg = ToRegister(instr->result()); 3323 Register reg = ToRegister(instr->result());
3297 __ Move(reg, Smi::FromInt(0)); 3324 __ Move(reg, Smi::FromInt(0));
3298 3325
3299 __ PushSafepointRegisters(); 3326 {
3300 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 3327 PushSafepointRegistersScope scope(this);
3301 RecordSafepointWithRegisters( 3328 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
3302 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); 3329 // Ensure that value in rax survives popping registers.
3303 // Ensure that value in rax survives popping registers. 3330 __ movq(kScratchRegister, rax);
3304 __ movq(kScratchRegister, rax); 3331 }
3305 __ PopSafepointRegisters();
3306 __ movq(reg, kScratchRegister); 3332 __ movq(reg, kScratchRegister);
3307 } 3333 }
3308 3334
3309 3335
3310 void LCodeGen::DoSmiTag(LSmiTag* instr) { 3336 void LCodeGen::DoSmiTag(LSmiTag* instr) {
3311 ASSERT(instr->InputAt(0)->Equals(instr->result())); 3337 ASSERT(instr->InputAt(0)->Equals(instr->result()));
3312 Register input = ToRegister(instr->InputAt(0)); 3338 Register input = ToRegister(instr->InputAt(0));
3313 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 3339 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
3314 __ Integer32ToSmi(input, input); 3340 __ Integer32ToSmi(input, input);
3315 } 3341 }
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after
3961 RegisterEnvironmentForDeoptimization(environment); 3987 RegisterEnvironmentForDeoptimization(environment);
3962 ASSERT(osr_pc_offset_ == -1); 3988 ASSERT(osr_pc_offset_ == -1);
3963 osr_pc_offset_ = masm()->pc_offset(); 3989 osr_pc_offset_ = masm()->pc_offset();
3964 } 3990 }
3965 3991
3966 #undef __ 3992 #undef __
3967 3993
3968 } } // namespace v8::internal 3994 } } // namespace v8::internal
3969 3995
3970 #endif // V8_TARGET_ARCH_X64 3996 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698