OLD | NEW |
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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 } | 288 } |
289 } | 289 } |
290 | 290 |
291 | 291 |
292 bool LCodeGen::GenerateDeferredCode() { | 292 bool LCodeGen::GenerateDeferredCode() { |
293 ASSERT(is_generating()); | 293 ASSERT(is_generating()); |
294 if (deferred_.length() > 0) { | 294 if (deferred_.length() > 0) { |
295 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 295 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
296 LDeferredCode* code = deferred_[i]; | 296 LDeferredCode* code = deferred_[i]; |
297 __ bind(code->entry()); | 297 __ bind(code->entry()); |
| 298 Comment(";;; Deferred code @%d: %s.", |
| 299 code->instruction_index(), |
| 300 code->instr()->Mnemonic()); |
298 code->Generate(); | 301 code->Generate(); |
299 __ jmp(code->exit()); | 302 __ jmp(code->exit()); |
300 } | 303 } |
301 | 304 |
302 // Pad code to ensure that the last piece of deferred code have | 305 // Pad code to ensure that the last piece of deferred code have |
303 // room for lazy bailout. | 306 // room for lazy bailout. |
304 while ((masm()->pc_offset() - LastSafepointEnd()) | 307 while ((masm()->pc_offset() - LastSafepointEnd()) |
305 < Deoptimizer::patch_size()) { | 308 < Deoptimizer::patch_size()) { |
306 __ nop(); | 309 __ nop(); |
307 } | 310 } |
(...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1897 | 1900 |
1898 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { | 1901 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { |
1899 class DeferredInstanceOfKnownGlobal: public LDeferredCode { | 1902 class DeferredInstanceOfKnownGlobal: public LDeferredCode { |
1900 public: | 1903 public: |
1901 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, | 1904 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, |
1902 LInstanceOfKnownGlobal* instr) | 1905 LInstanceOfKnownGlobal* instr) |
1903 : LDeferredCode(codegen), instr_(instr) { } | 1906 : LDeferredCode(codegen), instr_(instr) { } |
1904 virtual void Generate() { | 1907 virtual void Generate() { |
1905 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_); | 1908 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_); |
1906 } | 1909 } |
1907 | 1910 virtual LInstruction* instr() { return instr_; } |
1908 Label* map_check() { return &map_check_; } | 1911 Label* map_check() { return &map_check_; } |
1909 | |
1910 private: | 1912 private: |
1911 LInstanceOfKnownGlobal* instr_; | 1913 LInstanceOfKnownGlobal* instr_; |
1912 Label map_check_; | 1914 Label map_check_; |
1913 }; | 1915 }; |
1914 | 1916 |
1915 DeferredInstanceOfKnownGlobal* deferred; | 1917 DeferredInstanceOfKnownGlobal* deferred; |
1916 deferred = new DeferredInstanceOfKnownGlobal(this, instr); | 1918 deferred = new DeferredInstanceOfKnownGlobal(this, instr); |
1917 | 1919 |
1918 Label done, false_result; | 1920 Label done, false_result; |
1919 Register object = ToRegister(instr->InputAt(1)); | 1921 Register object = ToRegister(instr->InputAt(1)); |
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2752 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 2754 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
2753 // Class for deferred case. | 2755 // Class for deferred case. |
2754 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 2756 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
2755 public: | 2757 public: |
2756 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 2758 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
2757 LUnaryMathOperation* instr) | 2759 LUnaryMathOperation* instr) |
2758 : LDeferredCode(codegen), instr_(instr) { } | 2760 : LDeferredCode(codegen), instr_(instr) { } |
2759 virtual void Generate() { | 2761 virtual void Generate() { |
2760 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 2762 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
2761 } | 2763 } |
| 2764 virtual LInstruction* instr() { return instr_; } |
2762 private: | 2765 private: |
2763 LUnaryMathOperation* instr_; | 2766 LUnaryMathOperation* instr_; |
2764 }; | 2767 }; |
2765 | 2768 |
2766 ASSERT(instr->value()->Equals(instr->result())); | 2769 ASSERT(instr->value()->Equals(instr->result())); |
2767 Representation r = instr->hydrogen()->value()->representation(); | 2770 Representation r = instr->hydrogen()->value()->representation(); |
2768 | 2771 |
2769 if (r.IsDouble()) { | 2772 if (r.IsDouble()) { |
2770 XMMRegister scratch = xmm0; | 2773 XMMRegister scratch = xmm0; |
2771 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 2774 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3285 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3288 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
3286 } | 3289 } |
3287 | 3290 |
3288 | 3291 |
3289 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 3292 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
3290 class DeferredStringCharCodeAt: public LDeferredCode { | 3293 class DeferredStringCharCodeAt: public LDeferredCode { |
3291 public: | 3294 public: |
3292 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 3295 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
3293 : LDeferredCode(codegen), instr_(instr) { } | 3296 : LDeferredCode(codegen), instr_(instr) { } |
3294 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } | 3297 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } |
| 3298 virtual LInstruction* instr() { return instr_; } |
3295 private: | 3299 private: |
3296 LStringCharCodeAt* instr_; | 3300 LStringCharCodeAt* instr_; |
3297 }; | 3301 }; |
3298 | 3302 |
3299 Register string = ToRegister(instr->string()); | 3303 Register string = ToRegister(instr->string()); |
3300 Register index = ToRegister(instr->index()); | 3304 Register index = ToRegister(instr->index()); |
3301 Register result = ToRegister(instr->result()); | 3305 Register result = ToRegister(instr->result()); |
3302 | 3306 |
3303 DeferredStringCharCodeAt* deferred = | 3307 DeferredStringCharCodeAt* deferred = |
3304 new DeferredStringCharCodeAt(this, instr); | 3308 new DeferredStringCharCodeAt(this, instr); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3407 __ StoreToSafepointRegisterSlot(result, eax); | 3411 __ StoreToSafepointRegisterSlot(result, eax); |
3408 } | 3412 } |
3409 | 3413 |
3410 | 3414 |
3411 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { | 3415 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { |
3412 class DeferredStringCharFromCode: public LDeferredCode { | 3416 class DeferredStringCharFromCode: public LDeferredCode { |
3413 public: | 3417 public: |
3414 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) | 3418 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) |
3415 : LDeferredCode(codegen), instr_(instr) { } | 3419 : LDeferredCode(codegen), instr_(instr) { } |
3416 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } | 3420 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } |
| 3421 virtual LInstruction* instr() { return instr_; } |
3417 private: | 3422 private: |
3418 LStringCharFromCode* instr_; | 3423 LStringCharFromCode* instr_; |
3419 }; | 3424 }; |
3420 | 3425 |
3421 DeferredStringCharFromCode* deferred = | 3426 DeferredStringCharFromCode* deferred = |
3422 new DeferredStringCharFromCode(this, instr); | 3427 new DeferredStringCharFromCode(this, instr); |
3423 | 3428 |
3424 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); | 3429 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); |
3425 Register char_code = ToRegister(instr->char_code()); | 3430 Register char_code = ToRegister(instr->char_code()); |
3426 Register result = ToRegister(instr->result()); | 3431 Register result = ToRegister(instr->result()); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3486 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); | 3491 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); |
3487 } | 3492 } |
3488 | 3493 |
3489 | 3494 |
3490 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 3495 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
3491 class DeferredNumberTagI: public LDeferredCode { | 3496 class DeferredNumberTagI: public LDeferredCode { |
3492 public: | 3497 public: |
3493 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) | 3498 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) |
3494 : LDeferredCode(codegen), instr_(instr) { } | 3499 : LDeferredCode(codegen), instr_(instr) { } |
3495 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } | 3500 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } |
| 3501 virtual LInstruction* instr() { return instr_; } |
3496 private: | 3502 private: |
3497 LNumberTagI* instr_; | 3503 LNumberTagI* instr_; |
3498 }; | 3504 }; |
3499 | 3505 |
3500 LOperand* input = instr->InputAt(0); | 3506 LOperand* input = instr->InputAt(0); |
3501 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 3507 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
3502 Register reg = ToRegister(input); | 3508 Register reg = ToRegister(input); |
3503 | 3509 |
3504 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); | 3510 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); |
3505 __ SmiTag(reg); | 3511 __ SmiTag(reg); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3553 __ StoreToSafepointRegisterSlot(reg, reg); | 3559 __ StoreToSafepointRegisterSlot(reg, reg); |
3554 } | 3560 } |
3555 | 3561 |
3556 | 3562 |
3557 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 3563 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
3558 class DeferredNumberTagD: public LDeferredCode { | 3564 class DeferredNumberTagD: public LDeferredCode { |
3559 public: | 3565 public: |
3560 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 3566 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
3561 : LDeferredCode(codegen), instr_(instr) { } | 3567 : LDeferredCode(codegen), instr_(instr) { } |
3562 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } | 3568 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } |
| 3569 virtual LInstruction* instr() { return instr_; } |
3563 private: | 3570 private: |
3564 LNumberTagD* instr_; | 3571 LNumberTagD* instr_; |
3565 }; | 3572 }; |
3566 | 3573 |
3567 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); | 3574 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
3568 Register reg = ToRegister(instr->result()); | 3575 Register reg = ToRegister(instr->result()); |
3569 Register tmp = ToRegister(instr->TempAt(0)); | 3576 Register tmp = ToRegister(instr->TempAt(0)); |
3570 | 3577 |
3571 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); | 3578 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); |
3572 if (FLAG_inline_new) { | 3579 if (FLAG_inline_new) { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3654 | 3661 |
3655 // Smi to XMM conversion | 3662 // Smi to XMM conversion |
3656 __ bind(&load_smi); | 3663 __ bind(&load_smi); |
3657 __ SmiUntag(input_reg); // Untag smi before converting to float. | 3664 __ SmiUntag(input_reg); // Untag smi before converting to float. |
3658 __ cvtsi2sd(result_reg, Operand(input_reg)); | 3665 __ cvtsi2sd(result_reg, Operand(input_reg)); |
3659 __ SmiTag(input_reg); // Retag smi. | 3666 __ SmiTag(input_reg); // Retag smi. |
3660 __ bind(&done); | 3667 __ bind(&done); |
3661 } | 3668 } |
3662 | 3669 |
3663 | 3670 |
3664 class DeferredTaggedToI: public LDeferredCode { | |
3665 public: | |
3666 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | |
3667 : LDeferredCode(codegen), instr_(instr) { } | |
3668 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } | |
3669 private: | |
3670 LTaggedToI* instr_; | |
3671 }; | |
3672 | |
3673 | |
3674 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 3671 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { |
3675 Label done, heap_number; | 3672 Label done, heap_number; |
3676 Register input_reg = ToRegister(instr->InputAt(0)); | 3673 Register input_reg = ToRegister(instr->InputAt(0)); |
3677 | 3674 |
3678 // Heap number map check. | 3675 // Heap number map check. |
3679 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3676 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
3680 factory()->heap_number_map()); | 3677 factory()->heap_number_map()); |
3681 | 3678 |
3682 if (instr->truncating()) { | 3679 if (instr->truncating()) { |
3683 __ j(equal, &heap_number, Label::kNear); | 3680 __ j(equal, &heap_number, Label::kNear); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3745 __ movmskpd(input_reg, xmm0); | 3742 __ movmskpd(input_reg, xmm0); |
3746 __ and_(input_reg, 1); | 3743 __ and_(input_reg, 1); |
3747 DeoptimizeIf(not_zero, instr->environment()); | 3744 DeoptimizeIf(not_zero, instr->environment()); |
3748 } | 3745 } |
3749 } | 3746 } |
3750 __ bind(&done); | 3747 __ bind(&done); |
3751 } | 3748 } |
3752 | 3749 |
3753 | 3750 |
3754 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { | 3751 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { |
| 3752 class DeferredTaggedToI: public LDeferredCode { |
| 3753 public: |
| 3754 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) |
| 3755 : LDeferredCode(codegen), instr_(instr) { } |
| 3756 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } |
| 3757 virtual LInstruction* instr() { return instr_; } |
| 3758 private: |
| 3759 LTaggedToI* instr_; |
| 3760 }; |
| 3761 |
3755 LOperand* input = instr->InputAt(0); | 3762 LOperand* input = instr->InputAt(0); |
3756 ASSERT(input->IsRegister()); | 3763 ASSERT(input->IsRegister()); |
3757 ASSERT(input->Equals(instr->result())); | 3764 ASSERT(input->Equals(instr->result())); |
3758 | 3765 |
3759 Register input_reg = ToRegister(input); | 3766 Register input_reg = ToRegister(input); |
3760 | 3767 |
3761 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); | 3768 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); |
3762 | 3769 |
3763 // Smi check. | 3770 // Smi check. |
3764 __ JumpIfNotSmi(input_reg, deferred->entry()); | 3771 __ JumpIfNotSmi(input_reg, deferred->entry()); |
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4378 safepoints_.SetPcAfterGap(pc); | 4385 safepoints_.SetPcAfterGap(pc); |
4379 } | 4386 } |
4380 | 4387 |
4381 | 4388 |
4382 void LCodeGen::DoStackCheck(LStackCheck* instr) { | 4389 void LCodeGen::DoStackCheck(LStackCheck* instr) { |
4383 class DeferredStackCheck: public LDeferredCode { | 4390 class DeferredStackCheck: public LDeferredCode { |
4384 public: | 4391 public: |
4385 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) | 4392 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) |
4386 : LDeferredCode(codegen), instr_(instr) { } | 4393 : LDeferredCode(codegen), instr_(instr) { } |
4387 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } | 4394 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } |
| 4395 virtual LInstruction* instr() { return instr_; } |
4388 private: | 4396 private: |
4389 LStackCheck* instr_; | 4397 LStackCheck* instr_; |
4390 }; | 4398 }; |
4391 | 4399 |
4392 if (instr->hydrogen()->is_function_entry()) { | 4400 if (instr->hydrogen()->is_function_entry()) { |
4393 // Perform stack overflow check. | 4401 // Perform stack overflow check. |
4394 Label done; | 4402 Label done; |
4395 ExternalReference stack_limit = | 4403 ExternalReference stack_limit = |
4396 ExternalReference::address_of_stack_limit(isolate()); | 4404 ExternalReference::address_of_stack_limit(isolate()); |
4397 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 4405 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4460 env->deoptimization_index()); | 4468 env->deoptimization_index()); |
4461 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4469 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); |
4462 } | 4470 } |
4463 | 4471 |
4464 | 4472 |
4465 #undef __ | 4473 #undef __ |
4466 | 4474 |
4467 } } // namespace v8::internal | 4475 } } // namespace v8::internal |
4468 | 4476 |
4469 #endif // V8_TARGET_ARCH_IA32 | 4477 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |