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 |