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

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 21885003: Enables unboxed mints in ia32 javascript int compatability mode. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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 | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('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 (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 "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/locations.h" 13 #include "vm/locations.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/parser.h" 15 #include "vm/parser.h"
16 #include "vm/stack_frame.h" 16 #include "vm/stack_frame.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 #include "vm/symbols.h" 18 #include "vm/symbols.h"
19 19
20 #define __ compiler->assembler()-> 20 #define __ compiler->assembler()->
21 21
22 namespace dart { 22 namespace dart {
23 23
24 DECLARE_FLAG(int, optimization_counter_threshold); 24 DECLARE_FLAG(int, optimization_counter_threshold);
25 DECLARE_FLAG(bool, propagate_ic_data); 25 DECLARE_FLAG(bool, propagate_ic_data);
26 DECLARE_FLAG(bool, use_osr); 26 DECLARE_FLAG(bool, use_osr);
27 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
27 28
28 // Generic summary for call instructions that have all arguments pushed 29 // Generic summary for call instructions that have all arguments pushed
29 // on the stack and return the result in a fixed register EAX. 30 // on the stack and return the result in a fixed register EAX.
30 LocationSummary* Instruction::MakeCallSummary() { 31 LocationSummary* Instruction::MakeCallSummary() {
31 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); 32 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
32 result->set_out(Location::RegisterLocation(EAX)); 33 result->set_out(Location::RegisterLocation(EAX));
33 return result; 34 return result;
34 } 35 }
35 36
36 37
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 __ j(true_condition, &is_true); 642 __ j(true_condition, &is_true);
642 __ LoadObject(result, Bool::False()); 643 __ LoadObject(result, Bool::False());
643 __ jmp(&done); 644 __ jmp(&done);
644 __ Bind(&is_true); 645 __ Bind(&is_true);
645 __ LoadObject(result, Bool::True()); 646 __ LoadObject(result, Bool::True());
646 __ Bind(&done); 647 __ Bind(&done);
647 } 648 }
648 } 649 }
649 650
650 651
652 static void EmitJavascriptIntOverflowCheck(FlowGraphCompiler* compiler,
653 Label* overflow,
654 XmmRegister result,
655 Register tmp) {
656 // Compare upper half.
657 Label check_lower, done;
658 __ pextrd(tmp, result, Immediate(1));
659 __ cmpl(tmp, Immediate(0x00200000));
660 __ j(GREATER, overflow);
661 __ j(NOT_EQUAL, &check_lower);
662
663 __ pextrd(tmp, result, Immediate(0));
664 __ cmpl(tmp, Immediate(0));
665 __ j(ABOVE, overflow);
666
667 __ Bind(&check_lower);
668 __ pextrd(tmp, result, Immediate(1));
669 __ cmpl(tmp, Immediate(-0x00200000));
670 __ j(LESS, overflow);
671 // Anything in the lower part would make the number bigger than the lower
672 // bound, so we are done.
673
674 __ Bind(&done);
675 }
676
677
651 static Condition TokenKindToMintCondition(Token::Kind kind) { 678 static Condition TokenKindToMintCondition(Token::Kind kind) {
652 switch (kind) { 679 switch (kind) {
653 case Token::kEQ: return EQUAL; 680 case Token::kEQ: return EQUAL;
654 case Token::kNE: return NOT_EQUAL; 681 case Token::kNE: return NOT_EQUAL;
655 case Token::kLT: return LESS; 682 case Token::kLT: return LESS;
656 case Token::kGT: return GREATER; 683 case Token::kGT: return GREATER;
657 case Token::kLTE: return LESS_EQUAL; 684 case Token::kLTE: return LESS_EQUAL;
658 case Token::kGTE: return GREATER_EQUAL; 685 case Token::kGTE: return GREATER_EQUAL;
659 default: 686 default:
660 UNREACHABLE(); 687 UNREACHABLE();
(...skipping 3605 matching lines...) Expand 10 before | Expand all | Expand 10 after
4266 __ Bind(&done); 4293 __ Bind(&done);
4267 } 4294 }
4268 4295
4269 4296
4270 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { 4297 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const {
4271 const intptr_t kNumInputs = 2; 4298 const intptr_t kNumInputs = 2;
4272 switch (op_kind()) { 4299 switch (op_kind()) {
4273 case Token::kBIT_AND: 4300 case Token::kBIT_AND:
4274 case Token::kBIT_OR: 4301 case Token::kBIT_OR:
4275 case Token::kBIT_XOR: { 4302 case Token::kBIT_XOR: {
4276 const intptr_t kNumTemps = 0; 4303 const intptr_t kNumTemps =
4304 FLAG_throw_on_javascript_int_overflow ? 1 : 0;
4277 LocationSummary* summary = 4305 LocationSummary* summary =
4278 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4306 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4279 summary->set_in(0, Location::RequiresFpuRegister()); 4307 summary->set_in(0, Location::RequiresFpuRegister());
4280 summary->set_in(1, Location::RequiresFpuRegister()); 4308 summary->set_in(1, Location::RequiresFpuRegister());
4309 if (FLAG_throw_on_javascript_int_overflow) {
4310 summary->set_temp(0, Location::RequiresRegister());
4311 }
4281 summary->set_out(Location::SameAsFirstInput()); 4312 summary->set_out(Location::SameAsFirstInput());
4282 return summary; 4313 return summary;
4283 } 4314 }
4284 case Token::kADD: 4315 case Token::kADD:
4285 case Token::kSUB: { 4316 case Token::kSUB: {
4286 const intptr_t kNumTemps = 2; 4317 const intptr_t kNumTemps = 2;
4287 LocationSummary* summary = 4318 LocationSummary* summary =
4288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4319 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4289 summary->set_in(0, Location::RequiresFpuRegister()); 4320 summary->set_in(0, Location::RequiresFpuRegister());
4290 summary->set_in(1, Location::RequiresFpuRegister()); 4321 summary->set_in(1, Location::RequiresFpuRegister());
4291 summary->set_temp(0, Location::RequiresRegister()); 4322 summary->set_temp(0, Location::RequiresRegister());
4292 summary->set_temp(1, Location::RequiresRegister()); 4323 summary->set_temp(1, Location::RequiresRegister());
4293 summary->set_out(Location::SameAsFirstInput()); 4324 summary->set_out(Location::SameAsFirstInput());
4294 return summary; 4325 return summary;
4295 } 4326 }
4296 default: 4327 default:
4297 UNREACHABLE(); 4328 UNREACHABLE();
4298 return NULL; 4329 return NULL;
4299 } 4330 }
4300 } 4331 }
4301 4332
4302 4333
4303 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4334 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4304 XmmRegister left = locs()->in(0).fpu_reg(); 4335 XmmRegister left = locs()->in(0).fpu_reg();
4305 XmmRegister right = locs()->in(1).fpu_reg(); 4336 XmmRegister right = locs()->in(1).fpu_reg();
4306 4337
4307 ASSERT(locs()->out().fpu_reg() == left); 4338 ASSERT(locs()->out().fpu_reg() == left);
4308 4339
4340 Label* deopt = NULL;
4341 if (FLAG_throw_on_javascript_int_overflow) {
4342 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp);
4343 }
4309 switch (op_kind()) { 4344 switch (op_kind()) {
4310 case Token::kBIT_AND: __ andpd(left, right); break; 4345 case Token::kBIT_AND: __ andpd(left, right); break;
4311 case Token::kBIT_OR: __ orpd(left, right); break; 4346 case Token::kBIT_OR: __ orpd(left, right); break;
4312 case Token::kBIT_XOR: __ xorpd(left, right); break; 4347 case Token::kBIT_XOR: __ xorpd(left, right); break;
4313 case Token::kADD: 4348 case Token::kADD:
4314 case Token::kSUB: { 4349 case Token::kSUB: {
4315 Register lo = locs()->temp(0).reg(); 4350 Register lo = locs()->temp(0).reg();
4316 Register hi = locs()->temp(1).reg(); 4351 Register hi = locs()->temp(1).reg();
4317 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4352 if (!FLAG_throw_on_javascript_int_overflow) {
4318 kDeoptBinaryMintOp); 4353 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp);
4354 }
4355
4319 Label done, overflow; 4356 Label done, overflow;
4320 __ pextrd(lo, right, Immediate(0)); // Lower half 4357 __ pextrd(lo, right, Immediate(0)); // Lower half
4321 __ pextrd(hi, right, Immediate(1)); // Upper half 4358 __ pextrd(hi, right, Immediate(1)); // Upper half
4322 __ subl(ESP, Immediate(2 * kWordSize)); 4359 __ subl(ESP, Immediate(2 * kWordSize));
4323 __ movq(Address(ESP, 0), left); 4360 __ movq(Address(ESP, 0), left);
4324 if (op_kind() == Token::kADD) { 4361 if (op_kind() == Token::kADD) {
4325 __ addl(Address(ESP, 0), lo); 4362 __ addl(Address(ESP, 0), lo);
4326 __ adcl(Address(ESP, 1 * kWordSize), hi); 4363 __ adcl(Address(ESP, 1 * kWordSize), hi);
4327 } else { 4364 } else {
4328 __ subl(Address(ESP, 0), lo); 4365 __ subl(Address(ESP, 0), lo);
4329 __ sbbl(Address(ESP, 1 * kWordSize), hi); 4366 __ sbbl(Address(ESP, 1 * kWordSize), hi);
4330 } 4367 }
4331 __ j(OVERFLOW, &overflow); 4368 __ j(OVERFLOW, &overflow);
4332 __ movq(left, Address(ESP, 0)); 4369 __ movq(left, Address(ESP, 0));
4333 __ addl(ESP, Immediate(2 * kWordSize)); 4370 __ addl(ESP, Immediate(2 * kWordSize));
4334 __ jmp(&done); 4371 __ jmp(&done);
4335 __ Bind(&overflow); 4372 __ Bind(&overflow);
4336 __ addl(ESP, Immediate(2 * kWordSize)); 4373 __ addl(ESP, Immediate(2 * kWordSize));
4337 __ jmp(deopt); 4374 __ jmp(deopt);
4338 __ Bind(&done); 4375 __ Bind(&done);
4339 break; 4376 break;
4340 } 4377 }
4341 default: UNREACHABLE(); 4378 default: UNREACHABLE();
4342 } 4379 }
4380 if (FLAG_throw_on_javascript_int_overflow) {
4381 Register tmp = locs()->temp(0).reg();
4382 EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp);
4383 }
4343 } 4384 }
4344 4385
4345 4386
4346 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const { 4387 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const {
4347 const intptr_t kNumInputs = 2; 4388 const intptr_t kNumInputs = 2;
4348 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1; 4389 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1;
4349 LocationSummary* summary = 4390 LocationSummary* summary =
4350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4391 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4351 summary->set_in(0, Location::RequiresFpuRegister()); 4392 summary->set_in(0, Location::RequiresFpuRegister());
4352 summary->set_in(1, Location::RegisterLocation(ECX)); 4393 summary->set_in(1, Location::RegisterLocation(ECX));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4403 __ j(NOT_EQUAL, deopt); 4444 __ j(NOT_EQUAL, deopt);
4404 break; 4445 break;
4405 } 4446 }
4406 default: 4447 default:
4407 UNREACHABLE(); 4448 UNREACHABLE();
4408 break; 4449 break;
4409 } 4450 }
4410 __ movq(left, Address(ESP, 0)); 4451 __ movq(left, Address(ESP, 0));
4411 __ addl(ESP, Immediate(2 * kWordSize)); 4452 __ addl(ESP, Immediate(2 * kWordSize));
4412 __ Bind(&done); 4453 __ Bind(&done);
4454 if (FLAG_throw_on_javascript_int_overflow) {
4455 Register tmp = locs()->temp(0).reg();
4456 EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp);
4457 }
4413 } 4458 }
4414 4459
4415 4460
4416 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const { 4461 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const {
4417 const intptr_t kNumInputs = 1; 4462 const intptr_t kNumInputs = 1;
4418 const intptr_t kNumTemps = 0; 4463 const intptr_t kNumTemps =
4464 FLAG_throw_on_javascript_int_overflow ? 1 : 0;
4419 LocationSummary* summary = 4465 LocationSummary* summary =
4420 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4466 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4421 summary->set_in(0, Location::RequiresFpuRegister()); 4467 summary->set_in(0, Location::RequiresFpuRegister());
4422 summary->set_out(Location::SameAsFirstInput()); 4468 summary->set_out(Location::SameAsFirstInput());
4423 return summary; 4469 return summary;
4424 } 4470 }
4425 4471
4426 4472
4427 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4473 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4428 ASSERT(op_kind() == Token::kBIT_NOT); 4474 ASSERT(op_kind() == Token::kBIT_NOT);
4429 XmmRegister value = locs()->in(0).fpu_reg(); 4475 XmmRegister value = locs()->in(0).fpu_reg();
4430 ASSERT(value == locs()->out().fpu_reg()); 4476 ASSERT(value == locs()->out().fpu_reg());
4477 Label* deopt = NULL;
4478 if (FLAG_throw_on_javascript_int_overflow) {
4479 deopt = compiler->AddDeoptStub(deopt_id(),
4480 kDeoptUnaryMintOp);
4481 }
4431 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. 4482 __ pcmpeqq(XMM0, XMM0); // Generate all 1's.
4432 __ pxor(value, XMM0); 4483 __ pxor(value, XMM0);
4484 if (FLAG_throw_on_javascript_int_overflow) {
4485 Register tmp = locs()->temp(0).reg();
4486 EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp);
4487 }
4433 } 4488 }
4434 4489
4435 4490
4436 LocationSummary* ThrowInstr::MakeLocationSummary() const { 4491 LocationSummary* ThrowInstr::MakeLocationSummary() const {
4437 return new LocationSummary(0, 0, LocationSummary::kCall); 4492 return new LocationSummary(0, 0, LocationSummary::kCall);
4438 } 4493 }
4439 4494
4440 4495
4441 4496
4442 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4497 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
4875 PcDescriptors::kOther, 4930 PcDescriptors::kOther,
4876 locs()); 4931 locs());
4877 __ Drop(2); // Discard type arguments and receiver. 4932 __ Drop(2); // Discard type arguments and receiver.
4878 } 4933 }
4879 4934
4880 } // namespace dart 4935 } // namespace dart
4881 4936
4882 #undef __ 4937 #undef __
4883 4938
4884 #endif // defined TARGET_ARCH_IA32 4939 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698