Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 5664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5675 if (!is_smi()) { | 5675 if (!is_smi()) { |
| 5676 summary->set_temp(0, Location::RequiresRegister()); | 5676 summary->set_temp(0, Location::RequiresRegister()); |
| 5677 } | 5677 } |
| 5678 summary->set_out(0, Location::RequiresRegister()); | 5678 summary->set_out(0, Location::RequiresRegister()); |
| 5679 return summary; | 5679 return summary; |
| 5680 } | 5680 } |
| 5681 | 5681 |
| 5682 | 5682 |
| 5683 class BoxIntegerSlowPath : public SlowPathCode { | 5683 class BoxIntegerSlowPath : public SlowPathCode { |
| 5684 public: | 5684 public: |
| 5685 explicit BoxIntegerSlowPath(BoxIntegerInstr* instruction) | 5685 explicit BoxIntegerSlowPath(Definition* instruction) |
| 5686 : instruction_(instruction) { } | 5686 : instruction_(instruction) { } |
| 5687 | 5687 |
| 5688 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 5688 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5689 __ Comment("BoxIntegerSlowPath"); | 5689 __ Comment("BoxIntegerSlowPath"); |
| 5690 __ Bind(entry_label()); | 5690 __ Bind(entry_label()); |
| 5691 const Class& mint_class = | 5691 const Class& mint_class = |
| 5692 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()); | 5692 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()); |
| 5693 const Code& stub = | 5693 const Code& stub = |
| 5694 Code::Handle(StubCode::GetAllocationStubForClass(mint_class)); | 5694 Code::Handle(StubCode::GetAllocationStubForClass(mint_class)); |
| 5695 const ExternalLabel label(stub.EntryPoint()); | 5695 const ExternalLabel label(stub.EntryPoint()); |
| 5696 | 5696 |
| 5697 LocationSummary* locs = instruction_->locs(); | 5697 LocationSummary* locs = instruction_->locs(); |
| 5698 locs->live_registers()->Remove(locs->out(0)); | 5698 locs->live_registers()->Remove(locs->out(0)); |
| 5699 | 5699 |
| 5700 compiler->SaveLiveRegisters(locs); | 5700 compiler->SaveLiveRegisters(locs); |
| 5701 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 5701 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
| 5702 &label, | 5702 &label, |
| 5703 PcDescriptors::kOther, | 5703 PcDescriptors::kOther, |
| 5704 locs); | 5704 locs); |
| 5705 __ MoveRegister(locs->out(0).reg(), EAX); | 5705 __ MoveRegister(locs->out(0).reg(), EAX); |
| 5706 compiler->RestoreLiveRegisters(locs); | 5706 compiler->RestoreLiveRegisters(locs); |
| 5707 | 5707 |
| 5708 __ jmp(exit_label()); | 5708 __ jmp(exit_label()); |
| 5709 } | 5709 } |
| 5710 | 5710 |
| 5711 private: | 5711 private: |
| 5712 BoxIntegerInstr* instruction_; | 5712 Definition* instruction_; |
| 5713 }; | 5713 }; |
| 5714 | 5714 |
| 5715 | 5715 |
| 5716 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5716 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5717 if (is_smi()) { | 5717 if (is_smi()) { |
| 5718 PairLocation* value_pair = locs()->in(0).AsPairLocation(); | 5718 PairLocation* value_pair = locs()->in(0).AsPairLocation(); |
| 5719 Register value_lo = value_pair->At(0).reg(); | 5719 Register value_lo = value_pair->At(0).reg(); |
| 5720 Register out_reg = locs()->out(0).reg(); | 5720 Register out_reg = locs()->out(0).reg(); |
| 5721 __ movl(out_reg, value_lo); | 5721 __ movl(out_reg, value_lo); |
| 5722 __ SmiTag(out_reg); | 5722 __ SmiTag(out_reg); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5978 | 5978 |
| 5979 __ notl(left_lo); | 5979 __ notl(left_lo); |
| 5980 __ notl(left_hi); | 5980 __ notl(left_hi); |
| 5981 | 5981 |
| 5982 if (FLAG_throw_on_javascript_int_overflow) { | 5982 if (FLAG_throw_on_javascript_int_overflow) { |
| 5983 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | 5983 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); |
| 5984 } | 5984 } |
| 5985 } | 5985 } |
| 5986 | 5986 |
| 5987 | 5987 |
| 5988 LocationSummary* BinaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | |
| 5989 bool opt) const { | |
| 5990 const intptr_t kNumInputs = 2; | |
| 5991 const intptr_t kNumTemps = 0; | |
| 5992 LocationSummary* summary = new(isolate) LocationSummary( | |
| 5993 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 5994 summary->set_in(0, Location::RequiresRegister()); | |
| 5995 summary->set_in(1, Location::RequiresRegister()); | |
| 5996 summary->set_out(0, Location::SameAsFirstInput()); | |
| 5997 return summary; | |
| 5998 } | |
| 5999 | |
| 6000 | |
| 6001 void BinaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6002 Register left = locs()->in(0).reg(); | |
| 6003 Register right = locs()->in(1).reg(); | |
| 6004 Register out = locs()->out(0).reg(); | |
| 6005 ASSERT(out == left); | |
| 6006 switch (op_kind()) { | |
| 6007 case Token::kBIT_AND: | |
| 6008 __ andl(out, right); | |
| 6009 break; | |
| 6010 case Token::kBIT_OR: | |
| 6011 __ orl(out, right); | |
| 6012 break; | |
| 6013 case Token::kBIT_XOR: | |
| 6014 __ xorl(out, right); | |
| 6015 break; | |
| 6016 case Token::kADD: | |
| 6017 __ addl(out, right); | |
| 6018 break; | |
| 6019 case Token::kSUB: | |
| 6020 __ subl(out, right); | |
| 6021 break; | |
| 6022 default: | |
| 6023 UNREACHABLE(); | |
| 6024 } | |
| 6025 } | |
| 6026 | |
| 6027 | |
| 6028 LocationSummary* ShiftUint32OpInstr::MakeLocationSummary(Isolate* isolate, | |
| 6029 bool opt) const { | |
| 6030 const intptr_t kNumInputs = 2; | |
| 6031 const intptr_t kNumTemps = 0; | |
| 6032 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6033 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 6034 summary->set_in(0, Location::RequiresRegister()); | |
| 6035 summary->set_in(1, Location::RegisterLocation(ECX)); | |
|
Vyacheslav Egorov (Google)
2014/07/07 16:16:03
Please support constant operand as well. They are
Cutch
2014/07/07 22:34:28
Done.
| |
| 6036 summary->set_out(0, Location::SameAsFirstInput()); | |
| 6037 return summary; | |
| 6038 } | |
| 6039 | |
| 6040 | |
| 6041 void ShiftUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6042 Register left = locs()->in(0).reg(); | |
| 6043 Register shifter = locs()->in(1).reg(); | |
| 6044 Register out = locs()->out(0).reg(); | |
| 6045 ASSERT(left == out); | |
| 6046 ASSERT(shifter == ECX); | |
| 6047 | |
| 6048 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp); | |
| 6049 const Immediate& kCountLimit = Immediate(31); | |
| 6050 __ SmiUntag(shifter); | |
| 6051 __ cmpl(shifter, kCountLimit); | |
| 6052 __ j(ABOVE, deopt); | |
|
Vyacheslav Egorov (Google)
2014/07/07 16:16:04
is there any reason to deopt on shifts that are: 3
Cutch
2014/07/07 22:34:28
Done.
| |
| 6053 | |
| 6054 switch (op_kind()) { | |
| 6055 case Token::kSHR: | |
| 6056 __ shrl(left, shifter); | |
| 6057 break; | |
| 6058 case Token::kSHL: | |
| 6059 __ shll(left, shifter); | |
| 6060 break; | |
| 6061 default: | |
| 6062 UNREACHABLE(); | |
| 6063 } | |
| 6064 } | |
| 6065 | |
| 6066 | |
| 6067 LocationSummary* UnaryUint32OpInstr::MakeLocationSummary(Isolate* isolate, | |
| 6068 bool opt) const { | |
| 6069 const intptr_t kNumInputs = 1; | |
| 6070 const intptr_t kNumTemps = 0; | |
| 6071 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6072 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 6073 summary->set_in(0, Location::RequiresRegister()); | |
| 6074 summary->set_out(0, Location::SameAsFirstInput()); | |
| 6075 return summary; | |
| 6076 } | |
| 6077 | |
| 6078 | |
| 6079 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6080 Register out = locs()->out(0).reg(); | |
| 6081 ASSERT(locs()->in(0).reg() == out); | |
| 6082 | |
| 6083 ASSERT(op_kind() == Token::kBIT_NOT); | |
| 6084 | |
| 6085 __ notl(out); | |
| 6086 } | |
| 6087 | |
| 6088 | |
| 6089 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, | |
| 6090 bool opt) const { | |
| 6091 const intptr_t kNumInputs = 1; | |
| 6092 const intptr_t kNumTemps = 0; | |
| 6093 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6094 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | |
| 6095 summary->set_in(0, Location::RequiresRegister()); | |
| 6096 summary->set_out(0, Location::RequiresRegister()); | |
| 6097 return summary; | |
| 6098 } | |
| 6099 | |
| 6100 | |
| 6101 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6102 BoxIntegerSlowPath* slow_path = new BoxIntegerSlowPath(this); | |
| 6103 compiler->AddSlowPathCode(slow_path); | |
| 6104 Register value = locs()->in(0).reg(); | |
| 6105 Register out = locs()->out(0).reg(); | |
| 6106 ASSERT(value != out); | |
| 6107 | |
| 6108 Label not_smi, done; | |
| 6109 | |
| 6110 // Test if this value is <= kSmiMax. | |
| 6111 __ cmpl(value, Immediate(kSmiMax)); | |
| 6112 __ j(ABOVE, ¬_smi); | |
| 6113 // Smi. | |
| 6114 __ movl(out, value); | |
| 6115 __ SmiTag(out); | |
| 6116 __ jmp(&done); | |
| 6117 __ Bind(¬_smi); | |
| 6118 // Allocate a mint. | |
| 6119 __ TryAllocate( | |
| 6120 Class::ZoneHandle(Isolate::Current()->object_store()->mint_class()), | |
| 6121 slow_path->entry_label(), | |
| 6122 Assembler::kFarJump, | |
| 6123 out, | |
| 6124 kNoRegister); | |
| 6125 __ Bind(slow_path->exit_label()); | |
| 6126 // Copy low word into mint. | |
| 6127 __ movl(FieldAddress(out, Mint::value_offset()), value); | |
| 6128 // Zero high word. | |
| 6129 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0)); | |
| 6130 __ Bind(&done); | |
| 6131 } | |
| 6132 | |
| 6133 | |
| 6134 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, | |
| 6135 bool opt) const { | |
| 6136 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 6137 const intptr_t kNumInputs = 1; | |
| 6138 const intptr_t kNumTemps = | |
| 6139 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1; | |
| 6140 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6141 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 6142 summary->set_in(0, Location::RequiresRegister()); | |
| 6143 if (kNumTemps > 0) { | |
| 6144 summary->set_temp(0, Location::RequiresRegister()); | |
| 6145 } | |
| 6146 summary->set_out(0, Location::SameAsFirstInput()); | |
| 6147 return summary; | |
| 6148 } | |
| 6149 | |
| 6150 | |
| 6151 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6152 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 6153 const Register value = locs()->in(0).reg(); | |
| 6154 ASSERT(value == locs()->out(0).reg()); | |
| 6155 | |
| 6156 // TODO(johnmccutchan): Emit better code for constant inputs. | |
| 6157 if (value_cid == kMintCid) { | |
| 6158 __ movl(value, FieldAddress(value, Mint::value_offset())); | |
| 6159 } else if (value_cid == kSmiCid) { | |
| 6160 __ SmiUntag(value); | |
| 6161 } else { | |
| 6162 Register temp = locs()->temp(0).reg(); | |
| 6163 Label* deopt = compiler->AddDeoptStub(deopt_id_, | |
| 6164 ICData::kDeoptUnboxInteger); | |
| 6165 Label is_smi, done; | |
| 6166 __ testl(value, Immediate(kSmiTagMask)); | |
| 6167 __ j(ZERO, &is_smi); | |
| 6168 __ CompareClassId(value, kMintCid, temp); | |
| 6169 __ j(NOT_EQUAL, deopt); | |
| 6170 __ movl(value, FieldAddress(value, Mint::value_offset())); | |
| 6171 __ jmp(&done); | |
| 6172 __ Bind(&is_smi); | |
| 6173 __ SmiUntag(value); | |
| 6174 __ Bind(&done); | |
| 6175 } | |
| 6176 } | |
| 6177 | |
| 6178 | |
| 6179 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | |
| 6180 bool opt) const { | |
| 6181 const intptr_t kNumInputs = 1; | |
| 6182 const intptr_t kNumTemps = 0; | |
| 6183 LocationSummary* summary = new(isolate) LocationSummary( | |
| 6184 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 6185 if (from() == kUnboxedMint) { | |
| 6186 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | |
| 6187 Location::RequiresRegister())); | |
| 6188 summary->set_out(0, Location::RequiresRegister()); | |
| 6189 } else { | |
| 6190 ASSERT(from() == kUnboxedUint32); | |
| 6191 summary->set_in(0, Location::RequiresRegister()); | |
| 6192 summary->set_out(0, Location::Pair(Location::RequiresRegister(), | |
| 6193 Location::RequiresRegister())); | |
| 6194 } | |
| 6195 return summary; | |
| 6196 } | |
| 6197 | |
| 6198 | |
| 6199 void UnboxedIntConverterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 6200 if (from() == kUnboxedMint) { | |
| 6201 PairLocation* in_pair = locs()->in(0).AsPairLocation(); | |
| 6202 Register in_lo = in_pair->At(0).reg(); | |
| 6203 Register out = locs()->out(0).reg(); | |
| 6204 // Copy low word. | |
| 6205 __ movl(out, in_lo); | |
| 6206 } else { | |
| 6207 ASSERT(from() == kUnboxedUint32); | |
| 6208 Register in = locs()->in(0).reg(); | |
| 6209 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | |
| 6210 Register out_lo = out_pair->At(0).reg(); | |
| 6211 Register out_hi = out_pair->At(1).reg(); | |
| 6212 // Copy low word. | |
| 6213 __ movl(out_lo, in); | |
| 6214 // Zero upper word. | |
| 6215 __ xorl(out_hi, out_hi); | |
| 6216 } | |
| 6217 } | |
| 6218 | |
| 6219 | |
| 5988 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, | 6220 LocationSummary* ThrowInstr::MakeLocationSummary(Isolate* isolate, |
| 5989 bool opt) const { | 6221 bool opt) const { |
| 5990 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); | 6222 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kCall); |
| 5991 } | 6223 } |
| 5992 | 6224 |
| 5993 | 6225 |
| 5994 | 6226 |
| 5995 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6227 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5996 compiler->GenerateRuntimeCall(token_pos(), | 6228 compiler->GenerateRuntimeCall(token_pos(), |
| 5997 deopt_id(), | 6229 deopt_id(), |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6335 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6567 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6336 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6568 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6337 #endif | 6569 #endif |
| 6338 } | 6570 } |
| 6339 | 6571 |
| 6340 } // namespace dart | 6572 } // namespace dart |
| 6341 | 6573 |
| 6342 #undef __ | 6574 #undef __ |
| 6343 | 6575 |
| 6344 #endif // defined TARGET_ARCH_IA32 | 6576 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |