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

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

Issue 148573005: A64: Synchronize with r16249. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-gap-resolver-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 21 matching lines...) Expand all
32 #include "x64/lithium-codegen-x64.h" 32 #include "x64/lithium-codegen-x64.h"
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "stub-cache.h" 34 #include "stub-cache.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 39
40 // When invoking builtins, we need to record the safepoint in the middle of 40 // When invoking builtins, we need to record the safepoint in the middle of
41 // the invoke instruction sequence generated by the macro assembler. 41 // the invoke instruction sequence generated by the macro assembler.
42 class SafepointGenerator : public CallWrapper { 42 class SafepointGenerator V8_FINAL : public CallWrapper {
43 public: 43 public:
44 SafepointGenerator(LCodeGen* codegen, 44 SafepointGenerator(LCodeGen* codegen,
45 LPointerMap* pointers, 45 LPointerMap* pointers,
46 Safepoint::DeoptMode mode) 46 Safepoint::DeoptMode mode)
47 : codegen_(codegen), 47 : codegen_(codegen),
48 pointers_(pointers), 48 pointers_(pointers),
49 deopt_mode_(mode) { } 49 deopt_mode_(mode) { }
50 virtual ~SafepointGenerator() { } 50 virtual ~SafepointGenerator() {}
51 51
52 virtual void BeforeCall(int call_size) const { 52 virtual void BeforeCall(int call_size) const V8_OVERRIDE {
53 codegen_->EnsureSpaceForLazyDeopt(Deoptimizer::patch_size() - call_size); 53 codegen_->EnsureSpaceForLazyDeopt(Deoptimizer::patch_size() - call_size);
54 } 54 }
55 55
56 virtual void AfterCall() const { 56 virtual void AfterCall() const V8_OVERRIDE {
57 codegen_->RecordSafepoint(pointers_, deopt_mode_); 57 codegen_->RecordSafepoint(pointers_, deopt_mode_);
58 } 58 }
59 59
60 private: 60 private:
61 LCodeGen* codegen_; 61 LCodeGen* codegen_;
62 LPointerMap* pointers_; 62 LPointerMap* pointers_;
63 Safepoint::DeoptMode deopt_mode_; 63 Safepoint::DeoptMode deopt_mode_;
64 }; 64 };
65 65
66 66
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 power = WhichPowerOf2(-divisor); 1209 power = WhichPowerOf2(-divisor);
1210 } 1210 }
1211 1211
1212 if (test_value != 0) { 1212 if (test_value != 0) {
1213 if (instr->hydrogen()->CheckFlag( 1213 if (instr->hydrogen()->CheckFlag(
1214 HInstruction::kAllUsesTruncatingToInt32)) { 1214 HInstruction::kAllUsesTruncatingToInt32)) {
1215 Label done, negative; 1215 Label done, negative;
1216 __ cmpl(dividend, Immediate(0)); 1216 __ cmpl(dividend, Immediate(0));
1217 __ j(less, &negative, Label::kNear); 1217 __ j(less, &negative, Label::kNear);
1218 __ sarl(dividend, Immediate(power)); 1218 __ sarl(dividend, Immediate(power));
1219 if (divisor < 0) __ negl(dividend);
1219 __ jmp(&done, Label::kNear); 1220 __ jmp(&done, Label::kNear);
1220 1221
1221 __ bind(&negative); 1222 __ bind(&negative);
1222 __ negl(dividend); 1223 __ negl(dividend);
1223 __ sarl(dividend, Immediate(power)); 1224 __ sarl(dividend, Immediate(power));
1224 if (divisor > 0) __ negl(dividend); 1225 if (divisor > 0) __ negl(dividend);
1225 __ bind(&done); 1226 __ bind(&done);
1226 return; // Don't fall through to "__ neg" below. 1227 return; // Don't fall through to "__ neg" below.
1227 } else { 1228 } else {
1228 // Deoptimize if remainder is not 0. 1229 // Deoptimize if remainder is not 0.
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 __ j(cc, chunk_->GetAssemblyLabel(left_block)); 1894 __ j(cc, chunk_->GetAssemblyLabel(left_block));
1894 } else { 1895 } else {
1895 __ j(cc, chunk_->GetAssemblyLabel(left_block)); 1896 __ j(cc, chunk_->GetAssemblyLabel(left_block));
1896 if (cc != always) { 1897 if (cc != always) {
1897 __ jmp(chunk_->GetAssemblyLabel(right_block)); 1898 __ jmp(chunk_->GetAssemblyLabel(right_block));
1898 } 1899 }
1899 } 1900 }
1900 } 1901 }
1901 1902
1902 1903
1904 template<class InstrType>
1905 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
1906 int false_block = instr->FalseDestination(chunk_);
1907 __ j(cc, chunk_->GetAssemblyLabel(false_block));
1908 }
1909
1910
1903 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { 1911 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
1904 __ int3(); 1912 __ int3();
1905 } 1913 }
1906 1914
1907 1915
1908 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) { 1916 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
1909 Representation r = instr->hydrogen()->value()->representation(); 1917 Representation r = instr->hydrogen()->value()->representation();
1910 if (r.IsSmiOrInteger32() || r.IsDouble()) { 1918 if (r.IsSmiOrInteger32() || r.IsDouble()) {
1911 EmitBranch(instr, no_condition); 1919 EmitBranch(instr, no_condition);
1912 } else { 1920 } else {
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2166 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); 2174 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2167 __ CmpObject(left, right); 2175 __ CmpObject(left, right);
2168 } else { 2176 } else {
2169 Register right = ToRegister(instr->right()); 2177 Register right = ToRegister(instr->right());
2170 __ cmpq(left, right); 2178 __ cmpq(left, right);
2171 } 2179 }
2172 EmitBranch(instr, equal); 2180 EmitBranch(instr, equal);
2173 } 2181 }
2174 2182
2175 2183
2184 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
2185 if (instr->hydrogen()->representation().IsTagged()) {
2186 Register input_reg = ToRegister(instr->object());
2187 __ Cmp(input_reg, factory()->the_hole_value());
2188 EmitBranch(instr, equal);
2189 return;
2190 }
2191
2192 XMMRegister input_reg = ToDoubleRegister(instr->object());
2193 __ ucomisd(input_reg, input_reg);
2194 EmitFalseBranch(instr, parity_odd);
2195
2196 __ subq(rsp, Immediate(kDoubleSize));
2197 __ movsd(MemOperand(rsp, 0), input_reg);
2198 __ addq(rsp, Immediate(kDoubleSize));
2199
2200 int offset = sizeof(kHoleNanUpper32);
2201 __ cmpl(MemOperand(rsp, -offset), Immediate(kHoleNanUpper32));
2202 EmitBranch(instr, equal);
2203 }
2204
2205
2176 Condition LCodeGen::EmitIsObject(Register input, 2206 Condition LCodeGen::EmitIsObject(Register input,
2177 Label* is_not_object, 2207 Label* is_not_object,
2178 Label* is_object) { 2208 Label* is_object) {
2179 ASSERT(!input.is(kScratchRegister)); 2209 ASSERT(!input.is(kScratchRegister));
2180 2210
2181 __ JumpIfSmi(input, is_not_object); 2211 __ JumpIfSmi(input, is_not_object);
2182 2212
2183 __ CompareRoot(input, Heap::kNullValueRootIndex); 2213 __ CompareRoot(input, Heap::kNullValueRootIndex);
2184 __ j(equal, is_object); 2214 __ j(equal, is_object);
2185 2215
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
2430 __ j(zero, &true_value, Label::kNear); 2460 __ j(zero, &true_value, Label::kNear);
2431 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 2461 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
2432 __ jmp(&done, Label::kNear); 2462 __ jmp(&done, Label::kNear);
2433 __ bind(&true_value); 2463 __ bind(&true_value);
2434 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); 2464 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
2435 __ bind(&done); 2465 __ bind(&done);
2436 } 2466 }
2437 2467
2438 2468
2439 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 2469 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
2440 class DeferredInstanceOfKnownGlobal: public LDeferredCode { 2470 class DeferredInstanceOfKnownGlobal V8_FINAL : public LDeferredCode {
2441 public: 2471 public:
2442 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 2472 DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
2443 LInstanceOfKnownGlobal* instr) 2473 LInstanceOfKnownGlobal* instr)
2444 : LDeferredCode(codegen), instr_(instr) { } 2474 : LDeferredCode(codegen), instr_(instr) { }
2445 virtual void Generate() { 2475 virtual void Generate() V8_OVERRIDE {
2446 codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); 2476 codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
2447 } 2477 }
2448 virtual LInstruction* instr() { return instr_; } 2478 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
2449 Label* map_check() { return &map_check_; } 2479 Label* map_check() { return &map_check_; }
2450 private: 2480 private:
2451 LInstanceOfKnownGlobal* instr_; 2481 LInstanceOfKnownGlobal* instr_;
2452 Label map_check_; 2482 Label map_check_;
2453 }; 2483 };
2454 2484
2455 2485
2456 DeferredInstanceOfKnownGlobal* deferred; 2486 DeferredInstanceOfKnownGlobal* deferred;
2457 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); 2487 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
2458 2488
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2757 Register result = ToRegister(instr->result()); 2787 Register result = ToRegister(instr->result());
2758 if (access.IsInobject()) { 2788 if (access.IsInobject()) {
2759 __ movq(result, FieldOperand(object, offset)); 2789 __ movq(result, FieldOperand(object, offset));
2760 } else { 2790 } else {
2761 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2791 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
2762 __ movq(result, FieldOperand(result, offset)); 2792 __ movq(result, FieldOperand(result, offset));
2763 } 2793 }
2764 } 2794 }
2765 2795
2766 2796
2767 void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
2768 Register object,
2769 Handle<Map> type,
2770 Handle<String> name,
2771 LEnvironment* env) {
2772 LookupResult lookup(isolate());
2773 type->LookupDescriptor(NULL, *name, &lookup);
2774 ASSERT(lookup.IsFound() || lookup.IsCacheable());
2775 if (lookup.IsField()) {
2776 int index = lookup.GetLocalFieldIndexFromMap(*type);
2777 int offset = index * kPointerSize;
2778 if (index < 0) {
2779 // Negative property indices are in-object properties, indexed
2780 // from the end of the fixed part of the object.
2781 __ movq(result, FieldOperand(object, offset + type->instance_size()));
2782 } else {
2783 // Non-negative property indices are in the properties array.
2784 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
2785 __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
2786 }
2787 } else if (lookup.IsConstant()) {
2788 Handle<Object> constant(lookup.GetConstantFromMap(*type), isolate());
2789 __ LoadObject(result, constant);
2790 } else {
2791 // Negative lookup.
2792 // Check prototypes.
2793 Handle<HeapObject> current(HeapObject::cast((*type)->prototype()));
2794 Heap* heap = type->GetHeap();
2795 while (*current != heap->null_value()) {
2796 __ LoadHeapObject(result, current);
2797 __ Cmp(FieldOperand(result, HeapObject::kMapOffset),
2798 Handle<Map>(current->map()));
2799 DeoptimizeIf(not_equal, env);
2800 current =
2801 Handle<HeapObject>(HeapObject::cast(current->map()->prototype()));
2802 }
2803 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2804 }
2805 }
2806
2807
2808 // Check for cases where EmitLoadFieldOrConstantFunction needs to walk the
2809 // prototype chain, which causes unbounded code generation.
2810 static bool CompactEmit(SmallMapList* list,
2811 Handle<String> name,
2812 int i,
2813 Isolate* isolate) {
2814 Handle<Map> map = list->at(i);
2815 LookupResult lookup(isolate);
2816 map->LookupDescriptor(NULL, *name, &lookup);
2817 return lookup.IsField() || lookup.IsConstant();
2818 }
2819
2820
2821 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
2822 Register object = ToRegister(instr->object());
2823 Register result = ToRegister(instr->result());
2824
2825 int map_count = instr->hydrogen()->types()->length();
2826 bool need_generic = instr->hydrogen()->need_generic();
2827
2828 if (map_count == 0 && !need_generic) {
2829 DeoptimizeIf(no_condition, instr->environment());
2830 return;
2831 }
2832 Handle<String> name = instr->hydrogen()->name();
2833 Label done;
2834 bool all_are_compact = true;
2835 for (int i = 0; i < map_count; ++i) {
2836 if (!CompactEmit(instr->hydrogen()->types(), name, i, isolate())) {
2837 all_are_compact = false;
2838 break;
2839 }
2840 }
2841 for (int i = 0; i < map_count; ++i) {
2842 bool last = (i == map_count - 1);
2843 Handle<Map> map = instr->hydrogen()->types()->at(i);
2844 Label check_passed;
2845 __ CompareMap(object, map, &check_passed);
2846 if (last && !need_generic) {
2847 DeoptimizeIf(not_equal, instr->environment());
2848 __ bind(&check_passed);
2849 EmitLoadFieldOrConstantFunction(
2850 result, object, map, name, instr->environment());
2851 } else {
2852 Label next;
2853 bool compact = all_are_compact ? true :
2854 CompactEmit(instr->hydrogen()->types(), name, i, isolate());
2855 __ j(not_equal, &next, compact ? Label::kNear : Label::kFar);
2856 __ bind(&check_passed);
2857 EmitLoadFieldOrConstantFunction(
2858 result, object, map, name, instr->environment());
2859 __ jmp(&done, all_are_compact ? Label::kNear : Label::kFar);
2860 __ bind(&next);
2861 }
2862 }
2863 if (need_generic) {
2864 __ Move(rcx, name);
2865 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2866 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2867 }
2868 __ bind(&done);
2869 }
2870
2871
2872 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 2797 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
2873 ASSERT(ToRegister(instr->object()).is(rax)); 2798 ASSERT(ToRegister(instr->object()).is(rax));
2874 ASSERT(ToRegister(instr->result()).is(rax)); 2799 ASSERT(ToRegister(instr->result()).is(rax));
2875 2800
2876 __ Move(rcx, instr->name()); 2801 __ Move(rcx, instr->name());
2877 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2802 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2878 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2803 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2879 } 2804 }
2880 2805
2881 2806
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
3469 Label is_positive; 3394 Label is_positive;
3470 __ j(not_sign, &is_positive, Label::kNear); 3395 __ j(not_sign, &is_positive, Label::kNear);
3471 __ neg(input_reg); // Sets flags. 3396 __ neg(input_reg); // Sets flags.
3472 DeoptimizeIf(negative, instr->environment()); 3397 DeoptimizeIf(negative, instr->environment());
3473 __ bind(&is_positive); 3398 __ bind(&is_positive);
3474 } 3399 }
3475 3400
3476 3401
3477 void LCodeGen::DoMathAbs(LMathAbs* instr) { 3402 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3478 // Class for deferred case. 3403 // Class for deferred case.
3479 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3404 class DeferredMathAbsTaggedHeapNumber V8_FINAL : public LDeferredCode {
3480 public: 3405 public:
3481 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 3406 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3482 : LDeferredCode(codegen), instr_(instr) { } 3407 : LDeferredCode(codegen), instr_(instr) { }
3483 virtual void Generate() { 3408 virtual void Generate() V8_OVERRIDE {
3484 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3409 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3485 } 3410 }
3486 virtual LInstruction* instr() { return instr_; } 3411 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3487 private: 3412 private:
3488 LMathAbs* instr_; 3413 LMathAbs* instr_;
3489 }; 3414 };
3490 3415
3491 ASSERT(instr->value()->Equals(instr->result())); 3416 ASSERT(instr->value()->Equals(instr->result()));
3492 Representation r = instr->hydrogen()->value()->representation(); 3417 Representation r = instr->hydrogen()->value()->representation();
3493 3418
3494 if (r.IsDouble()) { 3419 if (r.IsDouble()) {
3495 XMMRegister scratch = xmm0; 3420 XMMRegister scratch = xmm0;
3496 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3421 XMMRegister input_reg = ToDoubleRegister(instr->value());
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
3701 __ CallStub(&stub); 3626 __ CallStub(&stub);
3702 } else { 3627 } else {
3703 ASSERT(exponent_type.IsDouble()); 3628 ASSERT(exponent_type.IsDouble());
3704 MathPowStub stub(MathPowStub::DOUBLE); 3629 MathPowStub stub(MathPowStub::DOUBLE);
3705 __ CallStub(&stub); 3630 __ CallStub(&stub);
3706 } 3631 }
3707 } 3632 }
3708 3633
3709 3634
3710 void LCodeGen::DoRandom(LRandom* instr) { 3635 void LCodeGen::DoRandom(LRandom* instr) {
3711 class DeferredDoRandom: public LDeferredCode { 3636 class DeferredDoRandom V8_FINAL : public LDeferredCode {
3712 public: 3637 public:
3713 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) 3638 DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
3714 : LDeferredCode(codegen), instr_(instr) { } 3639 : LDeferredCode(codegen), instr_(instr) { }
3715 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 3640 virtual void Generate() V8_OVERRIDE { codegen()->DoDeferredRandom(instr_); }
3716 virtual LInstruction* instr() { return instr_; } 3641 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3717 private: 3642 private:
3718 LRandom* instr_; 3643 LRandom* instr_;
3719 }; 3644 };
3720 3645
3721 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3646 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3722 3647
3723 // Having marked this instruction as a call we can use any 3648 // Having marked this instruction as a call we can use any
3724 // registers. 3649 // registers.
3725 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3650 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3726 3651
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after
4391 4316
4392 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4317 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4393 EmitPushTaggedOperand(instr->left()); 4318 EmitPushTaggedOperand(instr->left());
4394 EmitPushTaggedOperand(instr->right()); 4319 EmitPushTaggedOperand(instr->right());
4395 StringAddStub stub(instr->hydrogen()->flags()); 4320 StringAddStub stub(instr->hydrogen()->flags());
4396 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4321 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4397 } 4322 }
4398 4323
4399 4324
4400 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 4325 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
4401 class DeferredStringCharCodeAt: public LDeferredCode { 4326 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode {
4402 public: 4327 public:
4403 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 4328 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
4404 : LDeferredCode(codegen), instr_(instr) { } 4329 : LDeferredCode(codegen), instr_(instr) { }
4405 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } 4330 virtual void Generate() V8_OVERRIDE {
4406 virtual LInstruction* instr() { return instr_; } 4331 codegen()->DoDeferredStringCharCodeAt(instr_);
4332 }
4333 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4407 private: 4334 private:
4408 LStringCharCodeAt* instr_; 4335 LStringCharCodeAt* instr_;
4409 }; 4336 };
4410 4337
4411 DeferredStringCharCodeAt* deferred = 4338 DeferredStringCharCodeAt* deferred =
4412 new(zone()) DeferredStringCharCodeAt(this, instr); 4339 new(zone()) DeferredStringCharCodeAt(this, instr);
4413 4340
4414 StringCharLoadGenerator::Generate(masm(), 4341 StringCharLoadGenerator::Generate(masm(),
4415 ToRegister(instr->string()), 4342 ToRegister(instr->string()),
4416 ToRegister(instr->index()), 4343 ToRegister(instr->index()),
(...skipping 26 matching lines...) Expand all
4443 __ push(index); 4370 __ push(index);
4444 } 4371 }
4445 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr); 4372 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr);
4446 __ AssertSmi(rax); 4373 __ AssertSmi(rax);
4447 __ SmiToInteger32(rax, rax); 4374 __ SmiToInteger32(rax, rax);
4448 __ StoreToSafepointRegisterSlot(result, rax); 4375 __ StoreToSafepointRegisterSlot(result, rax);
4449 } 4376 }
4450 4377
4451 4378
4452 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 4379 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
4453 class DeferredStringCharFromCode: public LDeferredCode { 4380 class DeferredStringCharFromCode V8_FINAL : public LDeferredCode {
4454 public: 4381 public:
4455 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 4382 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
4456 : LDeferredCode(codegen), instr_(instr) { } 4383 : LDeferredCode(codegen), instr_(instr) { }
4457 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } 4384 virtual void Generate() V8_OVERRIDE {
4458 virtual LInstruction* instr() { return instr_; } 4385 codegen()->DoDeferredStringCharFromCode(instr_);
4386 }
4387 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4459 private: 4388 private:
4460 LStringCharFromCode* instr_; 4389 LStringCharFromCode* instr_;
4461 }; 4390 };
4462 4391
4463 DeferredStringCharFromCode* deferred = 4392 DeferredStringCharFromCode* deferred =
4464 new(zone()) DeferredStringCharFromCode(this, instr); 4393 new(zone()) DeferredStringCharFromCode(this, instr);
4465 4394
4466 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); 4395 ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
4467 Register char_code = ToRegister(instr->char_code()); 4396 Register char_code = ToRegister(instr->char_code());
4468 Register result = ToRegister(instr->result()); 4397 Register result = ToRegister(instr->result());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
4537 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4466 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4538 LOperand* input = instr->value(); 4467 LOperand* input = instr->value();
4539 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4468 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4540 Register reg = ToRegister(input); 4469 Register reg = ToRegister(input);
4541 4470
4542 __ Integer32ToSmi(reg, reg); 4471 __ Integer32ToSmi(reg, reg);
4543 } 4472 }
4544 4473
4545 4474
4546 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4475 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4547 class DeferredNumberTagU: public LDeferredCode { 4476 class DeferredNumberTagU V8_FINAL : public LDeferredCode {
4548 public: 4477 public:
4549 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4478 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4550 : LDeferredCode(codegen), instr_(instr) { } 4479 : LDeferredCode(codegen), instr_(instr) { }
4551 virtual void Generate() { 4480 virtual void Generate() V8_OVERRIDE {
4552 codegen()->DoDeferredNumberTagU(instr_); 4481 codegen()->DoDeferredNumberTagU(instr_);
4553 } 4482 }
4554 virtual LInstruction* instr() { return instr_; } 4483 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4555 private: 4484 private:
4556 LNumberTagU* instr_; 4485 LNumberTagU* instr_;
4557 }; 4486 };
4558 4487
4559 LOperand* input = instr->value(); 4488 LOperand* input = instr->value();
4560 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4489 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4561 Register reg = ToRegister(input); 4490 Register reg = ToRegister(input);
4562 4491
4563 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4492 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4564 __ cmpl(reg, Immediate(Smi::kMaxValue)); 4493 __ cmpl(reg, Immediate(Smi::kMaxValue));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4600 4529
4601 // Done. Put the value in xmm1 into the value of the allocated heap 4530 // Done. Put the value in xmm1 into the value of the allocated heap
4602 // number. 4531 // number.
4603 __ bind(&done); 4532 __ bind(&done);
4604 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1); 4533 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1);
4605 __ StoreToSafepointRegisterSlot(reg, reg); 4534 __ StoreToSafepointRegisterSlot(reg, reg);
4606 } 4535 }
4607 4536
4608 4537
4609 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4538 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4610 class DeferredNumberTagD: public LDeferredCode { 4539 class DeferredNumberTagD V8_FINAL : public LDeferredCode {
4611 public: 4540 public:
4612 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4541 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4613 : LDeferredCode(codegen), instr_(instr) { } 4542 : LDeferredCode(codegen), instr_(instr) { }
4614 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4543 virtual void Generate() V8_OVERRIDE {
4615 virtual LInstruction* instr() { return instr_; } 4544 codegen()->DoDeferredNumberTagD(instr_);
4545 }
4546 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4616 private: 4547 private:
4617 LNumberTagD* instr_; 4548 LNumberTagD* instr_;
4618 }; 4549 };
4619 4550
4620 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4551 XMMRegister input_reg = ToDoubleRegister(instr->value());
4621 Register reg = ToRegister(instr->result()); 4552 Register reg = ToRegister(instr->result());
4622 Register tmp = ToRegister(instr->temp()); 4553 Register tmp = ToRegister(instr->temp());
4623 4554
4624 bool convert_hole = false;
4625 HValue* change_input = instr->hydrogen()->value();
4626 if (change_input->IsLoadKeyed()) {
4627 HLoadKeyed* load = HLoadKeyed::cast(change_input);
4628 convert_hole = load->UsesMustHandleHole();
4629 }
4630
4631 Label no_special_nan_handling;
4632 Label done;
4633 if (convert_hole) {
4634 XMMRegister input_reg = ToDoubleRegister(instr->value());
4635 __ ucomisd(input_reg, input_reg);
4636 __ j(parity_odd, &no_special_nan_handling);
4637 __ subq(rsp, Immediate(kDoubleSize));
4638 __ movsd(MemOperand(rsp, 0), input_reg);
4639 __ cmpl(MemOperand(rsp, sizeof(kHoleNanLower32)),
4640 Immediate(kHoleNanUpper32));
4641 Label canonicalize;
4642 __ j(not_equal, &canonicalize);
4643 __ addq(rsp, Immediate(kDoubleSize));
4644 __ Move(reg, factory()->the_hole_value());
4645 __ jmp(&done);
4646 __ bind(&canonicalize);
4647 __ addq(rsp, Immediate(kDoubleSize));
4648 __ Set(kScratchRegister, BitCast<uint64_t>(
4649 FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
4650 __ movq(input_reg, kScratchRegister);
4651 }
4652
4653 __ bind(&no_special_nan_handling);
4654 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4555 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4655 if (FLAG_inline_new) { 4556 if (FLAG_inline_new) {
4656 __ AllocateHeapNumber(reg, tmp, deferred->entry()); 4557 __ AllocateHeapNumber(reg, tmp, deferred->entry());
4657 } else { 4558 } else {
4658 __ jmp(deferred->entry()); 4559 __ jmp(deferred->entry());
4659 } 4560 }
4660 __ bind(deferred->exit()); 4561 __ bind(deferred->exit());
4661 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 4562 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
4662
4663 __ bind(&done);
4664 } 4563 }
4665 4564
4666 4565
4667 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4566 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4668 // TODO(3095996): Get rid of this. For now, we need to make the 4567 // TODO(3095996): Get rid of this. For now, we need to make the
4669 // result register contain a valid pointer because it is already 4568 // result register contain a valid pointer because it is already
4670 // contained in the register pointer map. 4569 // contained in the register pointer map.
4671 Register reg = ToRegister(instr->result()); 4570 Register reg = ToRegister(instr->result());
4672 __ Move(reg, Smi::FromInt(0)); 4571 __ Move(reg, Smi::FromInt(0));
4673 4572
(...skipping 23 matching lines...) Expand all
4697 DeoptimizeIf(NegateCondition(is_smi), instr->environment()); 4596 DeoptimizeIf(NegateCondition(is_smi), instr->environment());
4698 } else { 4597 } else {
4699 __ AssertSmi(input); 4598 __ AssertSmi(input);
4700 } 4599 }
4701 __ SmiToInteger32(input, input); 4600 __ SmiToInteger32(input, input);
4702 } 4601 }
4703 4602
4704 4603
4705 void LCodeGen::EmitNumberUntagD(Register input_reg, 4604 void LCodeGen::EmitNumberUntagD(Register input_reg,
4706 XMMRegister result_reg, 4605 XMMRegister result_reg,
4707 bool allow_undefined_as_nan, 4606 bool can_convert_undefined_to_nan,
4708 bool deoptimize_on_minus_zero, 4607 bool deoptimize_on_minus_zero,
4709 LEnvironment* env, 4608 LEnvironment* env,
4710 NumberUntagDMode mode) { 4609 NumberUntagDMode mode) {
4711 Label load_smi, done; 4610 Label load_smi, done;
4712 4611
4713 STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE > 4612 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4714 NUMBER_CANDIDATE_IS_ANY_TAGGED);
4715 if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4716 // Smi check. 4613 // Smi check.
4717 __ JumpIfSmi(input_reg, &load_smi, Label::kNear); 4614 __ JumpIfSmi(input_reg, &load_smi, Label::kNear);
4718 4615
4719 // Heap number map check. 4616 // Heap number map check.
4720 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 4617 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
4721 Heap::kHeapNumberMapRootIndex); 4618 Heap::kHeapNumberMapRootIndex);
4722 if (!allow_undefined_as_nan) { 4619 if (!can_convert_undefined_to_nan) {
4723 DeoptimizeIf(not_equal, env); 4620 DeoptimizeIf(not_equal, env);
4724 } else { 4621 } else {
4725 Label heap_number, convert; 4622 Label heap_number, convert;
4726 __ j(equal, &heap_number, Label::kNear); 4623 __ j(equal, &heap_number, Label::kNear);
4727 4624
4728 // Convert undefined (and hole) to NaN. Compute NaN as 0/0. 4625 // Convert undefined (and hole) to NaN. Compute NaN as 0/0.
4729 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); 4626 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
4730 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) {
4731 __ j(equal, &convert, Label::kNear);
4732 __ CompareRoot(input_reg, Heap::kTheHoleValueRootIndex);
4733 }
4734 DeoptimizeIf(not_equal, env); 4627 DeoptimizeIf(not_equal, env);
4735 4628
4736 __ bind(&convert); 4629 __ bind(&convert);
4737 __ xorps(result_reg, result_reg); 4630 __ xorps(result_reg, result_reg);
4738 __ divsd(result_reg, result_reg); 4631 __ divsd(result_reg, result_reg);
4739 __ jmp(&done, Label::kNear); 4632 __ jmp(&done, Label::kNear);
4740 4633
4741 __ bind(&heap_number); 4634 __ bind(&heap_number);
4742 } 4635 }
4743 // Heap number to XMM conversion. 4636 // Heap number to XMM conversion.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4805 __ movmskpd(input_reg, xmm0); 4698 __ movmskpd(input_reg, xmm0);
4806 __ andl(input_reg, Immediate(1)); 4699 __ andl(input_reg, Immediate(1));
4807 DeoptimizeIf(not_zero, instr->environment()); 4700 DeoptimizeIf(not_zero, instr->environment());
4808 } 4701 }
4809 } 4702 }
4810 __ bind(&done); 4703 __ bind(&done);
4811 } 4704 }
4812 4705
4813 4706
4814 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 4707 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
4815 class DeferredTaggedToI: public LDeferredCode { 4708 class DeferredTaggedToI V8_FINAL : public LDeferredCode {
4816 public: 4709 public:
4817 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 4710 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
4818 : LDeferredCode(codegen), instr_(instr) { } 4711 : LDeferredCode(codegen), instr_(instr) { }
4819 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 4712 virtual void Generate() V8_OVERRIDE {
4820 virtual LInstruction* instr() { return instr_; } 4713 codegen()->DoDeferredTaggedToI(instr_);
4714 }
4715 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4821 private: 4716 private:
4822 LTaggedToI* instr_; 4717 LTaggedToI* instr_;
4823 }; 4718 };
4824 4719
4825 LOperand* input = instr->value(); 4720 LOperand* input = instr->value();
4826 ASSERT(input->IsRegister()); 4721 ASSERT(input->IsRegister());
4827 ASSERT(input->Equals(instr->result())); 4722 ASSERT(input->Equals(instr->result()));
4828 4723
4829 Register input_reg = ToRegister(input); 4724 Register input_reg = ToRegister(input);
4830 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 4725 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
4831 __ JumpIfNotSmi(input_reg, deferred->entry()); 4726 __ JumpIfNotSmi(input_reg, deferred->entry());
4832 __ SmiToInteger32(input_reg, input_reg); 4727 __ SmiToInteger32(input_reg, input_reg);
4833 __ bind(deferred->exit()); 4728 __ bind(deferred->exit());
4834 } 4729 }
4835 4730
4836 4731
4837 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4732 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
4838 LOperand* input = instr->value(); 4733 LOperand* input = instr->value();
4839 ASSERT(input->IsRegister()); 4734 ASSERT(input->IsRegister());
4840 LOperand* result = instr->result(); 4735 LOperand* result = instr->result();
4841 ASSERT(result->IsDoubleRegister()); 4736 ASSERT(result->IsDoubleRegister());
4842 4737
4843 Register input_reg = ToRegister(input); 4738 Register input_reg = ToRegister(input);
4844 XMMRegister result_reg = ToDoubleRegister(result); 4739 XMMRegister result_reg = ToDoubleRegister(result);
4845 4740
4846 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED;
4847 HValue* value = instr->hydrogen()->value(); 4741 HValue* value = instr->hydrogen()->value();
4848 if (value->type().IsSmi()) { 4742 NumberUntagDMode mode = value->representation().IsSmi()
4849 mode = NUMBER_CANDIDATE_IS_SMI; 4743 ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
4850 } else if (value->IsLoadKeyed()) {
4851 HLoadKeyed* load = HLoadKeyed::cast(value);
4852 if (load->UsesMustHandleHole()) {
4853 mode = NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE;
4854 }
4855 }
4856 4744
4857 EmitNumberUntagD(input_reg, result_reg, 4745 EmitNumberUntagD(input_reg, result_reg,
4858 instr->hydrogen()->allow_undefined_as_nan(), 4746 instr->hydrogen()->can_convert_undefined_to_nan(),
4859 instr->hydrogen()->deoptimize_on_minus_zero(), 4747 instr->hydrogen()->deoptimize_on_minus_zero(),
4860 instr->environment(), 4748 instr->environment(),
4861 mode); 4749 mode);
4862 } 4750 }
4863 4751
4864 4752
4865 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4753 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
4866 LOperand* input = instr->value(); 4754 LOperand* input = instr->value();
4867 ASSERT(input->IsDoubleRegister()); 4755 ASSERT(input->IsDoubleRegister());
4868 LOperand* result = instr->result(); 4756 LOperand* result = instr->result();
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
5014 PushSafepointRegistersScope scope(this); 4902 PushSafepointRegistersScope scope(this);
5015 __ push(object); 4903 __ push(object);
5016 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr); 4904 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr);
5017 __ testq(rax, Immediate(kSmiTagMask)); 4905 __ testq(rax, Immediate(kSmiTagMask));
5018 } 4906 }
5019 DeoptimizeIf(zero, instr->environment()); 4907 DeoptimizeIf(zero, instr->environment());
5020 } 4908 }
5021 4909
5022 4910
5023 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 4911 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
5024 class DeferredCheckMaps: public LDeferredCode { 4912 class DeferredCheckMaps V8_FINAL : public LDeferredCode {
5025 public: 4913 public:
5026 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 4914 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
5027 : LDeferredCode(codegen), instr_(instr), object_(object) { 4915 : LDeferredCode(codegen), instr_(instr), object_(object) {
5028 SetExit(check_maps()); 4916 SetExit(check_maps());
5029 } 4917 }
5030 virtual void Generate() { 4918 virtual void Generate() V8_OVERRIDE {
5031 codegen()->DoDeferredInstanceMigration(instr_, object_); 4919 codegen()->DoDeferredInstanceMigration(instr_, object_);
5032 } 4920 }
5033 Label* check_maps() { return &check_maps_; } 4921 Label* check_maps() { return &check_maps_; }
5034 virtual LInstruction* instr() { return instr_; } 4922 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5035 private: 4923 private:
5036 LCheckMaps* instr_; 4924 LCheckMaps* instr_;
5037 Label check_maps_; 4925 Label check_maps_;
5038 Register object_; 4926 Register object_;
5039 }; 4927 };
5040 4928
5041 if (instr->hydrogen()->CanOmitMapChecks()) return; 4929 if (instr->hydrogen()->CanOmitMapChecks()) return;
5042 4930
5043 LOperand* input = instr->value(); 4931 LOperand* input = instr->value();
5044 ASSERT(input->IsRegister()); 4932 ASSERT(input->IsRegister());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
5114 // smi 5002 // smi
5115 __ bind(&is_smi); 5003 __ bind(&is_smi);
5116 __ SmiToInteger32(input_reg, input_reg); 5004 __ SmiToInteger32(input_reg, input_reg);
5117 __ ClampUint8(input_reg); 5005 __ ClampUint8(input_reg);
5118 5006
5119 __ bind(&done); 5007 __ bind(&done);
5120 } 5008 }
5121 5009
5122 5010
5123 void LCodeGen::DoAllocate(LAllocate* instr) { 5011 void LCodeGen::DoAllocate(LAllocate* instr) {
5124 class DeferredAllocate: public LDeferredCode { 5012 class DeferredAllocate V8_FINAL : public LDeferredCode {
5125 public: 5013 public:
5126 DeferredAllocate(LCodeGen* codegen, LAllocate* instr) 5014 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5127 : LDeferredCode(codegen), instr_(instr) { } 5015 : LDeferredCode(codegen), instr_(instr) { }
5128 virtual void Generate() { codegen()->DoDeferredAllocate(instr_); } 5016 virtual void Generate() V8_OVERRIDE {
5129 virtual LInstruction* instr() { return instr_; } 5017 codegen()->DoDeferredAllocate(instr_);
5018 }
5019 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5130 private: 5020 private:
5131 LAllocate* instr_; 5021 LAllocate* instr_;
5132 }; 5022 };
5133 5023
5134 DeferredAllocate* deferred = 5024 DeferredAllocate* deferred =
5135 new(zone()) DeferredAllocate(this, instr); 5025 new(zone()) DeferredAllocate(this, instr);
5136 5026
5137 Register result = ToRegister(instr->result()); 5027 Register result = ToRegister(instr->result());
5138 Register temp = ToRegister(instr->temp()); 5028 Register temp = ToRegister(instr->temp());
5139 5029
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
5452 5342
5453 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 5343 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5454 Deoptimizer::BailoutType type = instr->hydrogen()->type(); 5344 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5455 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 5345 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
5456 // needed return address), even though the implementation of LAZY and EAGER is 5346 // needed return address), even though the implementation of LAZY and EAGER is
5457 // now identical. When LAZY is eventually completely folded into EAGER, remove 5347 // now identical. When LAZY is eventually completely folded into EAGER, remove
5458 // the special case below. 5348 // the special case below.
5459 if (info()->IsStub() && type == Deoptimizer::EAGER) { 5349 if (info()->IsStub() && type == Deoptimizer::EAGER) {
5460 type = Deoptimizer::LAZY; 5350 type = Deoptimizer::LAZY;
5461 } 5351 }
5352
5353 Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
5462 DeoptimizeIf(no_condition, instr->environment(), type); 5354 DeoptimizeIf(no_condition, instr->environment(), type);
5463 } 5355 }
5464 5356
5465 5357
5466 void LCodeGen::DoDummyUse(LDummyUse* instr) { 5358 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5467 // Nothing to see here, move on! 5359 // Nothing to see here, move on!
5468 } 5360 }
5469 5361
5470 5362
5471 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 5363 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5472 PushSafepointRegistersScope scope(this); 5364 PushSafepointRegistersScope scope(this);
5473 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 5365 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
5474 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 5366 __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
5475 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); 5367 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
5476 ASSERT(instr->HasEnvironment()); 5368 ASSERT(instr->HasEnvironment());
5477 LEnvironment* env = instr->environment(); 5369 LEnvironment* env = instr->environment();
5478 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5370 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5479 } 5371 }
5480 5372
5481 5373
5482 void LCodeGen::DoStackCheck(LStackCheck* instr) { 5374 void LCodeGen::DoStackCheck(LStackCheck* instr) {
5483 class DeferredStackCheck: public LDeferredCode { 5375 class DeferredStackCheck V8_FINAL : public LDeferredCode {
5484 public: 5376 public:
5485 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 5377 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
5486 : LDeferredCode(codegen), instr_(instr) { } 5378 : LDeferredCode(codegen), instr_(instr) { }
5487 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 5379 virtual void Generate() V8_OVERRIDE {
5488 virtual LInstruction* instr() { return instr_; } 5380 codegen()->DoDeferredStackCheck(instr_);
5381 }
5382 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
5489 private: 5383 private:
5490 LStackCheck* instr_; 5384 LStackCheck* instr_;
5491 }; 5385 };
5492 5386
5493 ASSERT(instr->HasEnvironment()); 5387 ASSERT(instr->HasEnvironment());
5494 LEnvironment* env = instr->environment(); 5388 LEnvironment* env = instr->environment();
5495 // There is no LLazyBailout instruction for stack-checks. We have to 5389 // There is no LLazyBailout instruction for stack-checks. We have to
5496 // prepare for lazy deoptimization explicitly here. 5390 // prepare for lazy deoptimization explicitly here.
5497 if (instr->hydrogen()->is_function_entry()) { 5391 if (instr->hydrogen()->is_function_entry()) {
5498 // Perform stack overflow check. 5392 // Perform stack overflow check.
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
5629 FixedArray::kHeaderSize - kPointerSize)); 5523 FixedArray::kHeaderSize - kPointerSize));
5630 __ bind(&done); 5524 __ bind(&done);
5631 } 5525 }
5632 5526
5633 5527
5634 #undef __ 5528 #undef __
5635 5529
5636 } } // namespace v8::internal 5530 } } // namespace v8::internal
5637 5531
5638 #endif // V8_TARGET_ARCH_X64 5532 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-gap-resolver-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698