| 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 |