| 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/compiler.h" | 10 #include "vm/compiler.h" |
| 11 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
| 12 #include "vm/flow_graph.h" | 12 #include "vm/flow_graph.h" |
| 13 #include "vm/flow_graph_compiler.h" | 13 #include "vm/flow_graph_compiler.h" |
| 14 #include "vm/flow_graph_range_analysis.h" | 14 #include "vm/flow_graph_range_analysis.h" |
| 15 #include "vm/locations.h" | 15 #include "vm/locations.h" |
| 16 #include "vm/object_store.h" | 16 #include "vm/object_store.h" |
| 17 #include "vm/parser.h" | 17 #include "vm/parser.h" |
| 18 #include "vm/stack_frame.h" | 18 #include "vm/stack_frame.h" |
| 19 #include "vm/stub_code.h" | 19 #include "vm/stub_code.h" |
| 20 #include "vm/symbols.h" | 20 #include "vm/symbols.h" |
| 21 | 21 |
| 22 #define __ compiler->assembler()-> | 22 #define __ compiler->assembler()-> |
| 23 | 23 |
| 24 namespace dart { | 24 namespace dart { |
| 25 | 25 |
| 26 DECLARE_FLAG(bool, emit_edge_counters); | 26 DECLARE_FLAG(bool, emit_edge_counters); |
| 27 DECLARE_FLAG(int, optimization_counter_threshold); | 27 DECLARE_FLAG(int, optimization_counter_threshold); |
| 28 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | |
| 29 DECLARE_FLAG(bool, use_osr); | 28 DECLARE_FLAG(bool, use_osr); |
| 30 | 29 |
| 31 // Generic summary for call instructions that have all arguments pushed | 30 // Generic summary for call instructions that have all arguments pushed |
| 32 // on the stack and return the result in a fixed register EAX. | 31 // on the stack and return the result in a fixed register EAX. |
| 33 LocationSummary* Instruction::MakeCallSummary(Zone* zone) { | 32 LocationSummary* Instruction::MakeCallSummary(Zone* zone) { |
| 34 const intptr_t kNumInputs = 0; | 33 const intptr_t kNumInputs = 0; |
| 35 const intptr_t kNumTemps = 0; | 34 const intptr_t kNumTemps = 0; |
| 36 LocationSummary* result = new(zone) LocationSummary( | 35 LocationSummary* result = new(zone) LocationSummary( |
| 37 zone, kNumInputs, kNumTemps, LocationSummary::kCall); | 36 zone, kNumInputs, kNumTemps, LocationSummary::kCall); |
| 38 result->set_out(0, Location::RegisterLocation(EAX)); | 37 result->set_out(0, Location::RegisterLocation(EAX)); |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 __ CompareObject(left.reg(), right.constant()); | 433 __ CompareObject(left.reg(), right.constant()); |
| 435 } else if (right.IsStackSlot()) { | 434 } else if (right.IsStackSlot()) { |
| 436 __ cmpl(left.reg(), right.ToStackSlotAddress()); | 435 __ cmpl(left.reg(), right.ToStackSlotAddress()); |
| 437 } else { | 436 } else { |
| 438 __ cmpl(left.reg(), right.reg()); | 437 __ cmpl(left.reg(), right.reg()); |
| 439 } | 438 } |
| 440 return true_condition; | 439 return true_condition; |
| 441 } | 440 } |
| 442 | 441 |
| 443 | 442 |
| 444 static void EmitJavascriptIntOverflowCheck(FlowGraphCompiler* compiler, | |
| 445 Label* overflow, | |
| 446 Register result_lo, | |
| 447 Register result_hi) { | |
| 448 // Compare upper half. | |
| 449 Label check_lower; | |
| 450 __ cmpl(result_hi, Immediate(0x00200000)); | |
| 451 __ j(GREATER, overflow); | |
| 452 __ j(NOT_EQUAL, &check_lower); | |
| 453 | |
| 454 __ cmpl(result_lo, Immediate(0)); | |
| 455 __ j(ABOVE, overflow); | |
| 456 | |
| 457 __ Bind(&check_lower); | |
| 458 __ cmpl(result_hi, Immediate(-0x00200000)); | |
| 459 __ j(LESS, overflow); | |
| 460 // Anything in the lower part would make the number bigger than the lower | |
| 461 // bound, so we are done. | |
| 462 } | |
| 463 | |
| 464 | |
| 465 static Condition TokenKindToMintCondition(Token::Kind kind) { | 443 static Condition TokenKindToMintCondition(Token::Kind kind) { |
| 466 switch (kind) { | 444 switch (kind) { |
| 467 case Token::kEQ: return EQUAL; | 445 case Token::kEQ: return EQUAL; |
| 468 case Token::kNE: return NOT_EQUAL; | 446 case Token::kNE: return NOT_EQUAL; |
| 469 case Token::kLT: return LESS; | 447 case Token::kLT: return LESS; |
| 470 case Token::kGT: return GREATER; | 448 case Token::kGT: return GREATER; |
| 471 case Token::kLTE: return LESS_EQUAL; | 449 case Token::kLTE: return LESS_EQUAL; |
| 472 case Token::kGTE: return GREATER_EQUAL; | 450 case Token::kGTE: return GREATER_EQUAL; |
| 473 default: | 451 default: |
| 474 UNREACHABLE(); | 452 UNREACHABLE(); |
| (...skipping 5553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6028 __ j(NOT_EQUAL, deopt); | 6006 __ j(NOT_EQUAL, deopt); |
| 6029 ASSERT(left_lo == EAX); | 6007 ASSERT(left_lo == EAX); |
| 6030 __ imull(right_lo); // Result in EDX:EAX. | 6008 __ imull(right_lo); // Result in EDX:EAX. |
| 6031 ASSERT(out_lo == EAX); | 6009 ASSERT(out_lo == EAX); |
| 6032 ASSERT(out_hi == EDX); | 6010 ASSERT(out_hi == EDX); |
| 6033 break; | 6011 break; |
| 6034 } | 6012 } |
| 6035 default: | 6013 default: |
| 6036 UNREACHABLE(); | 6014 UNREACHABLE(); |
| 6037 } | 6015 } |
| 6038 if (FLAG_throw_on_javascript_int_overflow) { | |
| 6039 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | |
| 6040 } | |
| 6041 } | 6016 } |
| 6042 | 6017 |
| 6043 | 6018 |
| 6044 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone, | 6019 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Zone* zone, |
| 6045 bool opt) const { | 6020 bool opt) const { |
| 6046 const intptr_t kNumInputs = 2; | 6021 const intptr_t kNumInputs = 2; |
| 6047 const intptr_t kNumTemps = | 6022 const intptr_t kNumTemps = |
| 6048 (op_kind() == Token::kSHL) && CanDeoptimize() ? 2 : 0; | 6023 (op_kind() == Token::kSHL) && CanDeoptimize() ? 2 : 0; |
| 6049 LocationSummary* summary = new(zone) LocationSummary( | 6024 LocationSummary* summary = new(zone) LocationSummary( |
| 6050 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6025 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6230 __ xorl(left_lo, left_lo); // Zero left_lo. | 6205 __ xorl(left_lo, left_lo); // Zero left_lo. |
| 6231 __ shll(left_hi, ECX); // Shift count: CL % 32. | 6206 __ shll(left_hi, ECX); // Shift count: CL % 32. |
| 6232 } | 6207 } |
| 6233 break; | 6208 break; |
| 6234 } | 6209 } |
| 6235 default: | 6210 default: |
| 6236 UNREACHABLE(); | 6211 UNREACHABLE(); |
| 6237 } | 6212 } |
| 6238 __ Bind(&done); | 6213 __ Bind(&done); |
| 6239 } | 6214 } |
| 6240 if (FLAG_throw_on_javascript_int_overflow) { | |
| 6241 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | |
| 6242 } | |
| 6243 } | 6215 } |
| 6244 | 6216 |
| 6245 | 6217 |
| 6246 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone, | 6218 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Zone* zone, |
| 6247 bool opt) const { | 6219 bool opt) const { |
| 6248 const intptr_t kNumInputs = 1; | 6220 const intptr_t kNumInputs = 1; |
| 6249 const intptr_t kNumTemps = 0; | 6221 const intptr_t kNumTemps = 0; |
| 6250 LocationSummary* summary = new(zone) LocationSummary( | 6222 LocationSummary* summary = new(zone) LocationSummary( |
| 6251 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6223 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 6252 summary->set_in(0, Location::Pair(Location::RequiresRegister(), | 6224 summary->set_in(0, Location::Pair(Location::RequiresRegister(), |
| 6253 Location::RequiresRegister())); | 6225 Location::RequiresRegister())); |
| 6254 summary->set_out(0, Location::SameAsFirstInput()); | 6226 summary->set_out(0, Location::SameAsFirstInput()); |
| 6255 if (FLAG_throw_on_javascript_int_overflow) { | |
| 6256 summary->set_temp(0, Location::RequiresRegister()); | |
| 6257 } | |
| 6258 return summary; | 6227 return summary; |
| 6259 } | 6228 } |
| 6260 | 6229 |
| 6261 | 6230 |
| 6262 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6231 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6263 ASSERT(op_kind() == Token::kBIT_NOT); | 6232 ASSERT(op_kind() == Token::kBIT_NOT); |
| 6264 PairLocation* left_pair = locs()->in(0).AsPairLocation(); | 6233 PairLocation* left_pair = locs()->in(0).AsPairLocation(); |
| 6265 Register left_lo = left_pair->At(0).reg(); | 6234 Register left_lo = left_pair->At(0).reg(); |
| 6266 Register left_hi = left_pair->At(1).reg(); | 6235 Register left_hi = left_pair->At(1).reg(); |
| 6267 PairLocation* out_pair = locs()->out(0).AsPairLocation(); | 6236 PairLocation* out_pair = locs()->out(0).AsPairLocation(); |
| 6268 Register out_lo = out_pair->At(0).reg(); | 6237 Register out_lo = out_pair->At(0).reg(); |
| 6269 Register out_hi = out_pair->At(1).reg(); | 6238 Register out_hi = out_pair->At(1).reg(); |
| 6270 ASSERT(out_lo == left_lo); | 6239 ASSERT(out_lo == left_lo); |
| 6271 ASSERT(out_hi == left_hi); | 6240 ASSERT(out_hi == left_hi); |
| 6272 | |
| 6273 Label* deopt = NULL; | |
| 6274 if (FLAG_throw_on_javascript_int_overflow) { | |
| 6275 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryMintOp); | |
| 6276 } | |
| 6277 | |
| 6278 __ notl(left_lo); | 6241 __ notl(left_lo); |
| 6279 __ notl(left_hi); | 6242 __ notl(left_hi); |
| 6280 | |
| 6281 if (FLAG_throw_on_javascript_int_overflow) { | |
| 6282 EmitJavascriptIntOverflowCheck(compiler, deopt, left_lo, left_hi); | |
| 6283 } | |
| 6284 } | 6243 } |
| 6285 | 6244 |
| 6286 | 6245 |
| 6287 CompileType BinaryUint32OpInstr::ComputeType() const { | 6246 CompileType BinaryUint32OpInstr::ComputeType() const { |
| 6288 return CompileType::Int(); | 6247 return CompileType::Int(); |
| 6289 } | 6248 } |
| 6290 | 6249 |
| 6291 | 6250 |
| 6292 CompileType ShiftUint32OpInstr::ComputeType() const { | 6251 CompileType ShiftUint32OpInstr::ComputeType() const { |
| 6293 return CompileType::Int(); | 6252 return CompileType::Int(); |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6877 __ Drop(1); | 6836 __ Drop(1); |
| 6878 __ popl(result); | 6837 __ popl(result); |
| 6879 } | 6838 } |
| 6880 | 6839 |
| 6881 | 6840 |
| 6882 } // namespace dart | 6841 } // namespace dart |
| 6883 | 6842 |
| 6884 #undef __ | 6843 #undef __ |
| 6885 | 6844 |
| 6886 #endif // defined TARGET_ARCH_IA32 | 6845 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |