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 |