| 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 return !is_aborted(); | 276 return !is_aborted(); |
| 277 } | 277 } |
| 278 | 278 |
| 279 | 279 |
| 280 bool LCodeGen::GenerateDeferredCode() { | 280 bool LCodeGen::GenerateDeferredCode() { |
| 281 ASSERT(is_generating()); | 281 ASSERT(is_generating()); |
| 282 if (deferred_.length() > 0) { | 282 if (deferred_.length() > 0) { |
| 283 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 283 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
| 284 LDeferredCode* code = deferred_[i]; | 284 LDeferredCode* code = deferred_[i]; |
| 285 __ bind(code->entry()); | 285 __ bind(code->entry()); |
| 286 Comment(";;; Deferred code @%d: %s.", |
| 287 code->instruction_index(), |
| 288 code->instr()->Mnemonic()); |
| 286 code->Generate(); | 289 code->Generate(); |
| 287 __ jmp(code->exit()); | 290 __ jmp(code->exit()); |
| 288 } | 291 } |
| 289 | 292 |
| 290 // Pad code to ensure that the last piece of deferred code have | 293 // Pad code to ensure that the last piece of deferred code have |
| 291 // room for lazy bailout. | 294 // room for lazy bailout. |
| 292 while ((masm()->pc_offset() - LastSafepointEnd()) | 295 while ((masm()->pc_offset() - LastSafepointEnd()) |
| 293 < Deoptimizer::patch_size()) { | 296 < Deoptimizer::patch_size()) { |
| 294 int padding = masm()->pc_offset() - LastSafepointEnd(); | 297 int padding = masm()->pc_offset() - LastSafepointEnd(); |
| 295 if (padding > 9) { | 298 if (padding > 9) { |
| (...skipping 1567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1863 | 1866 |
| 1864 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { | 1867 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { |
| 1865 class DeferredInstanceOfKnownGlobal: public LDeferredCode { | 1868 class DeferredInstanceOfKnownGlobal: public LDeferredCode { |
| 1866 public: | 1869 public: |
| 1867 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, | 1870 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, |
| 1868 LInstanceOfKnownGlobal* instr) | 1871 LInstanceOfKnownGlobal* instr) |
| 1869 : LDeferredCode(codegen), instr_(instr) { } | 1872 : LDeferredCode(codegen), instr_(instr) { } |
| 1870 virtual void Generate() { | 1873 virtual void Generate() { |
| 1871 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_); | 1874 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_); |
| 1872 } | 1875 } |
| 1873 | 1876 virtual LInstruction* instr() { return instr_; } |
| 1874 Label* map_check() { return &map_check_; } | 1877 Label* map_check() { return &map_check_; } |
| 1875 | |
| 1876 private: | 1878 private: |
| 1877 LInstanceOfKnownGlobal* instr_; | 1879 LInstanceOfKnownGlobal* instr_; |
| 1878 Label map_check_; | 1880 Label map_check_; |
| 1879 }; | 1881 }; |
| 1880 | 1882 |
| 1881 | 1883 |
| 1882 DeferredInstanceOfKnownGlobal* deferred; | 1884 DeferredInstanceOfKnownGlobal* deferred; |
| 1883 deferred = new DeferredInstanceOfKnownGlobal(this, instr); | 1885 deferred = new DeferredInstanceOfKnownGlobal(this, instr); |
| 1884 | 1886 |
| 1885 Label done, false_result; | 1887 Label done, false_result; |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2706 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 2708 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
| 2707 // Class for deferred case. | 2709 // Class for deferred case. |
| 2708 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 2710 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 2709 public: | 2711 public: |
| 2710 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 2712 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
| 2711 LUnaryMathOperation* instr) | 2713 LUnaryMathOperation* instr) |
| 2712 : LDeferredCode(codegen), instr_(instr) { } | 2714 : LDeferredCode(codegen), instr_(instr) { } |
| 2713 virtual void Generate() { | 2715 virtual void Generate() { |
| 2714 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 2716 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
| 2715 } | 2717 } |
| 2718 virtual LInstruction* instr() { return instr_; } |
| 2716 private: | 2719 private: |
| 2717 LUnaryMathOperation* instr_; | 2720 LUnaryMathOperation* instr_; |
| 2718 }; | 2721 }; |
| 2719 | 2722 |
| 2720 ASSERT(instr->InputAt(0)->Equals(instr->result())); | 2723 ASSERT(instr->InputAt(0)->Equals(instr->result())); |
| 2721 Representation r = instr->hydrogen()->value()->representation(); | 2724 Representation r = instr->hydrogen()->value()->representation(); |
| 2722 | 2725 |
| 2723 if (r.IsDouble()) { | 2726 if (r.IsDouble()) { |
| 2724 XMMRegister scratch = xmm0; | 2727 XMMRegister scratch = xmm0; |
| 2725 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); | 2728 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3222 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 3225 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
| 3223 } | 3226 } |
| 3224 | 3227 |
| 3225 | 3228 |
| 3226 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 3229 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
| 3227 class DeferredStringCharCodeAt: public LDeferredCode { | 3230 class DeferredStringCharCodeAt: public LDeferredCode { |
| 3228 public: | 3231 public: |
| 3229 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 3232 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
| 3230 : LDeferredCode(codegen), instr_(instr) { } | 3233 : LDeferredCode(codegen), instr_(instr) { } |
| 3231 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } | 3234 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } |
| 3235 virtual LInstruction* instr() { return instr_; } |
| 3232 private: | 3236 private: |
| 3233 LStringCharCodeAt* instr_; | 3237 LStringCharCodeAt* instr_; |
| 3234 }; | 3238 }; |
| 3235 | 3239 |
| 3236 Register string = ToRegister(instr->string()); | 3240 Register string = ToRegister(instr->string()); |
| 3237 Register index = ToRegister(instr->index()); | 3241 Register index = ToRegister(instr->index()); |
| 3238 Register result = ToRegister(instr->result()); | 3242 Register result = ToRegister(instr->result()); |
| 3239 | 3243 |
| 3240 DeferredStringCharCodeAt* deferred = | 3244 DeferredStringCharCodeAt* deferred = |
| 3241 new DeferredStringCharCodeAt(this, instr); | 3245 new DeferredStringCharCodeAt(this, instr); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3342 __ StoreToSafepointRegisterSlot(result, rax); | 3346 __ StoreToSafepointRegisterSlot(result, rax); |
| 3343 } | 3347 } |
| 3344 | 3348 |
| 3345 | 3349 |
| 3346 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { | 3350 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { |
| 3347 class DeferredStringCharFromCode: public LDeferredCode { | 3351 class DeferredStringCharFromCode: public LDeferredCode { |
| 3348 public: | 3352 public: |
| 3349 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) | 3353 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) |
| 3350 : LDeferredCode(codegen), instr_(instr) { } | 3354 : LDeferredCode(codegen), instr_(instr) { } |
| 3351 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } | 3355 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } |
| 3356 virtual LInstruction* instr() { return instr_; } |
| 3352 private: | 3357 private: |
| 3353 LStringCharFromCode* instr_; | 3358 LStringCharFromCode* instr_; |
| 3354 }; | 3359 }; |
| 3355 | 3360 |
| 3356 DeferredStringCharFromCode* deferred = | 3361 DeferredStringCharFromCode* deferred = |
| 3357 new DeferredStringCharFromCode(this, instr); | 3362 new DeferredStringCharFromCode(this, instr); |
| 3358 | 3363 |
| 3359 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); | 3364 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); |
| 3360 Register char_code = ToRegister(instr->char_code()); | 3365 Register char_code = ToRegister(instr->char_code()); |
| 3361 Register result = ToRegister(instr->result()); | 3366 Register result = ToRegister(instr->result()); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3418 __ Integer32ToSmi(reg, reg); | 3423 __ Integer32ToSmi(reg, reg); |
| 3419 } | 3424 } |
| 3420 | 3425 |
| 3421 | 3426 |
| 3422 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 3427 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
| 3423 class DeferredNumberTagD: public LDeferredCode { | 3428 class DeferredNumberTagD: public LDeferredCode { |
| 3424 public: | 3429 public: |
| 3425 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 3430 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
| 3426 : LDeferredCode(codegen), instr_(instr) { } | 3431 : LDeferredCode(codegen), instr_(instr) { } |
| 3427 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } | 3432 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } |
| 3433 virtual LInstruction* instr() { return instr_; } |
| 3428 private: | 3434 private: |
| 3429 LNumberTagD* instr_; | 3435 LNumberTagD* instr_; |
| 3430 }; | 3436 }; |
| 3431 | 3437 |
| 3432 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); | 3438 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| 3433 Register reg = ToRegister(instr->result()); | 3439 Register reg = ToRegister(instr->result()); |
| 3434 Register tmp = ToRegister(instr->TempAt(0)); | 3440 Register tmp = ToRegister(instr->TempAt(0)); |
| 3435 | 3441 |
| 3436 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); | 3442 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); |
| 3437 if (FLAG_inline_new) { | 3443 if (FLAG_inline_new) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3513 __ jmp(&done, Label::kNear); | 3519 __ jmp(&done, Label::kNear); |
| 3514 | 3520 |
| 3515 // Smi to XMM conversion | 3521 // Smi to XMM conversion |
| 3516 __ bind(&load_smi); | 3522 __ bind(&load_smi); |
| 3517 __ SmiToInteger32(kScratchRegister, input_reg); | 3523 __ SmiToInteger32(kScratchRegister, input_reg); |
| 3518 __ cvtlsi2sd(result_reg, kScratchRegister); | 3524 __ cvtlsi2sd(result_reg, kScratchRegister); |
| 3519 __ bind(&done); | 3525 __ bind(&done); |
| 3520 } | 3526 } |
| 3521 | 3527 |
| 3522 | 3528 |
| 3523 class DeferredTaggedToI: public LDeferredCode { | |
| 3524 public: | |
| 3525 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | |
| 3526 : LDeferredCode(codegen), instr_(instr) { } | |
| 3527 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } | |
| 3528 private: | |
| 3529 LTaggedToI* instr_; | |
| 3530 }; | |
| 3531 | |
| 3532 | |
| 3533 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 3529 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { |
| 3534 Label done, heap_number; | 3530 Label done, heap_number; |
| 3535 Register input_reg = ToRegister(instr->InputAt(0)); | 3531 Register input_reg = ToRegister(instr->InputAt(0)); |
| 3536 | 3532 |
| 3537 // Heap number map check. | 3533 // Heap number map check. |
| 3538 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), | 3534 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 3539 Heap::kHeapNumberMapRootIndex); | 3535 Heap::kHeapNumberMapRootIndex); |
| 3540 | 3536 |
| 3541 if (instr->truncating()) { | 3537 if (instr->truncating()) { |
| 3542 __ j(equal, &heap_number, Label::kNear); | 3538 __ j(equal, &heap_number, Label::kNear); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3571 __ movmskpd(input_reg, xmm0); | 3567 __ movmskpd(input_reg, xmm0); |
| 3572 __ andl(input_reg, Immediate(1)); | 3568 __ andl(input_reg, Immediate(1)); |
| 3573 DeoptimizeIf(not_zero, instr->environment()); | 3569 DeoptimizeIf(not_zero, instr->environment()); |
| 3574 } | 3570 } |
| 3575 } | 3571 } |
| 3576 __ bind(&done); | 3572 __ bind(&done); |
| 3577 } | 3573 } |
| 3578 | 3574 |
| 3579 | 3575 |
| 3580 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { | 3576 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { |
| 3577 class DeferredTaggedToI: public LDeferredCode { |
| 3578 public: |
| 3579 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) |
| 3580 : LDeferredCode(codegen), instr_(instr) { } |
| 3581 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } |
| 3582 virtual LInstruction* instr() { return instr_; } |
| 3583 private: |
| 3584 LTaggedToI* instr_; |
| 3585 }; |
| 3586 |
| 3581 LOperand* input = instr->InputAt(0); | 3587 LOperand* input = instr->InputAt(0); |
| 3582 ASSERT(input->IsRegister()); | 3588 ASSERT(input->IsRegister()); |
| 3583 ASSERT(input->Equals(instr->result())); | 3589 ASSERT(input->Equals(instr->result())); |
| 3584 | 3590 |
| 3585 Register input_reg = ToRegister(input); | 3591 Register input_reg = ToRegister(input); |
| 3586 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); | 3592 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); |
| 3587 __ JumpIfNotSmi(input_reg, deferred->entry()); | 3593 __ JumpIfNotSmi(input_reg, deferred->entry()); |
| 3588 __ SmiToInteger32(input_reg, input_reg); | 3594 __ SmiToInteger32(input_reg, input_reg); |
| 3589 __ bind(deferred->exit()); | 3595 __ bind(deferred->exit()); |
| 3590 } | 3596 } |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4138 safepoints_.SetPcAfterGap(pc); | 4144 safepoints_.SetPcAfterGap(pc); |
| 4139 } | 4145 } |
| 4140 | 4146 |
| 4141 | 4147 |
| 4142 void LCodeGen::DoStackCheck(LStackCheck* instr) { | 4148 void LCodeGen::DoStackCheck(LStackCheck* instr) { |
| 4143 class DeferredStackCheck: public LDeferredCode { | 4149 class DeferredStackCheck: public LDeferredCode { |
| 4144 public: | 4150 public: |
| 4145 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) | 4151 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) |
| 4146 : LDeferredCode(codegen), instr_(instr) { } | 4152 : LDeferredCode(codegen), instr_(instr) { } |
| 4147 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } | 4153 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } |
| 4154 virtual LInstruction* instr() { return instr_; } |
| 4148 private: | 4155 private: |
| 4149 LStackCheck* instr_; | 4156 LStackCheck* instr_; |
| 4150 }; | 4157 }; |
| 4151 | 4158 |
| 4152 if (instr->hydrogen()->is_function_entry()) { | 4159 if (instr->hydrogen()->is_function_entry()) { |
| 4153 // Perform stack overflow check. | 4160 // Perform stack overflow check. |
| 4154 Label done; | 4161 Label done; |
| 4155 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 4162 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
| 4156 __ j(above_equal, &done, Label::kNear); | 4163 __ j(above_equal, &done, Label::kNear); |
| 4157 StackCheckStub stub; | 4164 StackCheckStub stub; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 4184 RegisterEnvironmentForDeoptimization(environment); | 4191 RegisterEnvironmentForDeoptimization(environment); |
| 4185 ASSERT(osr_pc_offset_ == -1); | 4192 ASSERT(osr_pc_offset_ == -1); |
| 4186 osr_pc_offset_ = masm()->pc_offset(); | 4193 osr_pc_offset_ = masm()->pc_offset(); |
| 4187 } | 4194 } |
| 4188 | 4195 |
| 4189 #undef __ | 4196 #undef __ |
| 4190 | 4197 |
| 4191 } } // namespace v8::internal | 4198 } } // namespace v8::internal |
| 4192 | 4199 |
| 4193 #endif // V8_TARGET_ARCH_X64 | 4200 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |