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

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
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 if (FLAG_throw_on_javascript_int_overflow) {
srdjan 2013/08/02 18:07:22 I would move this test at call sites, think it is
zra 2013/08/02 18:30:27 Done.
657 // Compare upper half.
658 Label check_lower, done;
659 __ pextrd(tmp, result, Immediate(1));
660 __ cmpl(tmp, Immediate(0x00200000));
661 __ j(GREATER, overflow);
662 __ j(NOT_EQUAL, &check_lower);
663
664 __ pextrd(tmp, result, Immediate(0));
665 __ cmpl(tmp, Immediate(0));
666 __ j(ABOVE, overflow);
667
668 __ Bind(&check_lower);
669 __ pextrd(tmp, result, Immediate(1));
670 __ cmpl(tmp, Immediate(-0x00200000));
671 __ j(LESS, overflow);
672 // Anything in the lower part would make the number bigger than the lower
673 // bound, so we are done.
674
675 __ Bind(&done);
676 }
677 }
678
679
651 static Condition TokenKindToMintCondition(Token::Kind kind) { 680 static Condition TokenKindToMintCondition(Token::Kind kind) {
652 switch (kind) { 681 switch (kind) {
653 case Token::kEQ: return EQUAL; 682 case Token::kEQ: return EQUAL;
654 case Token::kNE: return NOT_EQUAL; 683 case Token::kNE: return NOT_EQUAL;
655 case Token::kLT: return LESS; 684 case Token::kLT: return LESS;
656 case Token::kGT: return GREATER; 685 case Token::kGT: return GREATER;
657 case Token::kLTE: return LESS_EQUAL; 686 case Token::kLTE: return LESS_EQUAL;
658 case Token::kGTE: return GREATER_EQUAL; 687 case Token::kGTE: return GREATER_EQUAL;
659 default: 688 default:
660 UNREACHABLE(); 689 UNREACHABLE();
(...skipping 3605 matching lines...) Expand 10 before | Expand all | Expand 10 after
4266 __ Bind(&done); 4295 __ Bind(&done);
4267 } 4296 }
4268 4297
4269 4298
4270 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { 4299 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const {
4271 const intptr_t kNumInputs = 2; 4300 const intptr_t kNumInputs = 2;
4272 switch (op_kind()) { 4301 switch (op_kind()) {
4273 case Token::kBIT_AND: 4302 case Token::kBIT_AND:
4274 case Token::kBIT_OR: 4303 case Token::kBIT_OR:
4275 case Token::kBIT_XOR: { 4304 case Token::kBIT_XOR: {
4276 const intptr_t kNumTemps = 0; 4305 const intptr_t kNumTemps =
4306 FLAG_throw_on_javascript_int_overflow ? 1 : 0;
4277 LocationSummary* summary = 4307 LocationSummary* summary =
4278 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4308 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4279 summary->set_in(0, Location::RequiresFpuRegister()); 4309 summary->set_in(0, Location::RequiresFpuRegister());
4280 summary->set_in(1, Location::RequiresFpuRegister()); 4310 summary->set_in(1, Location::RequiresFpuRegister());
4311 if (FLAG_throw_on_javascript_int_overflow) {
4312 summary->set_temp(0, Location::RequiresRegister());
4313 }
4281 summary->set_out(Location::SameAsFirstInput()); 4314 summary->set_out(Location::SameAsFirstInput());
4282 return summary; 4315 return summary;
4283 } 4316 }
4284 case Token::kADD: 4317 case Token::kADD:
4285 case Token::kSUB: { 4318 case Token::kSUB: {
4286 const intptr_t kNumTemps = 2; 4319 const intptr_t kNumTemps = 2;
4287 LocationSummary* summary = 4320 LocationSummary* summary =
4288 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4321 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4289 summary->set_in(0, Location::RequiresFpuRegister()); 4322 summary->set_in(0, Location::RequiresFpuRegister());
4290 summary->set_in(1, Location::RequiresFpuRegister()); 4323 summary->set_in(1, Location::RequiresFpuRegister());
4291 summary->set_temp(0, Location::RequiresRegister()); 4324 summary->set_temp(0, Location::RequiresRegister());
4292 summary->set_temp(1, Location::RequiresRegister()); 4325 summary->set_temp(1, Location::RequiresRegister());
4293 summary->set_out(Location::SameAsFirstInput()); 4326 summary->set_out(Location::SameAsFirstInput());
4294 return summary; 4327 return summary;
4295 } 4328 }
4296 default: 4329 default:
4297 UNREACHABLE(); 4330 UNREACHABLE();
4298 return NULL; 4331 return NULL;
4299 } 4332 }
4300 } 4333 }
4301 4334
4302 4335
4303 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4336 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4304 XmmRegister left = locs()->in(0).fpu_reg(); 4337 XmmRegister left = locs()->in(0).fpu_reg();
4305 XmmRegister right = locs()->in(1).fpu_reg(); 4338 XmmRegister right = locs()->in(1).fpu_reg();
4306 4339
4307 ASSERT(locs()->out().fpu_reg() == left); 4340 ASSERT(locs()->out().fpu_reg() == left);
4308 4341
4342 Label* deopt = NULL;
4343 if (FLAG_throw_on_javascript_int_overflow) {
4344 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp);
4345 }
4309 switch (op_kind()) { 4346 switch (op_kind()) {
4310 case Token::kBIT_AND: __ andpd(left, right); break; 4347 case Token::kBIT_AND: __ andpd(left, right); break;
4311 case Token::kBIT_OR: __ orpd(left, right); break; 4348 case Token::kBIT_OR: __ orpd(left, right); break;
4312 case Token::kBIT_XOR: __ xorpd(left, right); break; 4349 case Token::kBIT_XOR: __ xorpd(left, right); break;
4313 case Token::kADD: 4350 case Token::kADD:
4314 case Token::kSUB: { 4351 case Token::kSUB: {
4315 Register lo = locs()->temp(0).reg(); 4352 Register lo = locs()->temp(0).reg();
4316 Register hi = locs()->temp(1).reg(); 4353 Register hi = locs()->temp(1).reg();
4317 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4354 if (!FLAG_throw_on_javascript_int_overflow) {
4318 kDeoptBinaryMintOp); 4355 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp);
4356 }
4357
4319 Label done, overflow; 4358 Label done, overflow;
4320 __ pextrd(lo, right, Immediate(0)); // Lower half 4359 __ pextrd(lo, right, Immediate(0)); // Lower half
4321 __ pextrd(hi, right, Immediate(1)); // Upper half 4360 __ pextrd(hi, right, Immediate(1)); // Upper half
4322 __ subl(ESP, Immediate(2 * kWordSize)); 4361 __ subl(ESP, Immediate(2 * kWordSize));
4323 __ movq(Address(ESP, 0), left); 4362 __ movq(Address(ESP, 0), left);
4324 if (op_kind() == Token::kADD) { 4363 if (op_kind() == Token::kADD) {
4325 __ addl(Address(ESP, 0), lo); 4364 __ addl(Address(ESP, 0), lo);
4326 __ adcl(Address(ESP, 1 * kWordSize), hi); 4365 __ adcl(Address(ESP, 1 * kWordSize), hi);
4327 } else { 4366 } else {
4328 __ subl(Address(ESP, 0), lo); 4367 __ subl(Address(ESP, 0), lo);
4329 __ sbbl(Address(ESP, 1 * kWordSize), hi); 4368 __ sbbl(Address(ESP, 1 * kWordSize), hi);
4330 } 4369 }
4331 __ j(OVERFLOW, &overflow); 4370 __ j(OVERFLOW, &overflow);
4332 __ movq(left, Address(ESP, 0)); 4371 __ movq(left, Address(ESP, 0));
4333 __ addl(ESP, Immediate(2 * kWordSize)); 4372 __ addl(ESP, Immediate(2 * kWordSize));
4334 __ jmp(&done); 4373 __ jmp(&done);
4335 __ Bind(&overflow); 4374 __ Bind(&overflow);
4336 __ addl(ESP, Immediate(2 * kWordSize)); 4375 __ addl(ESP, Immediate(2 * kWordSize));
4337 __ jmp(deopt); 4376 __ jmp(deopt);
4338 __ Bind(&done); 4377 __ Bind(&done);
4339 break; 4378 break;
4340 } 4379 }
4341 default: UNREACHABLE(); 4380 default: UNREACHABLE();
4342 } 4381 }
4382 if (FLAG_throw_on_javascript_int_overflow) {
4383 Register tmp = locs()->temp(0).reg();
4384 EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp);
4385 }
4343 } 4386 }
4344 4387
4345 4388
4346 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const { 4389 LocationSummary* ShiftMintOpInstr::MakeLocationSummary() const {
4347 const intptr_t kNumInputs = 2; 4390 const intptr_t kNumInputs = 2;
4348 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1; 4391 const intptr_t kNumTemps = op_kind() == Token::kSHL ? 2 : 1;
4349 LocationSummary* summary = 4392 LocationSummary* summary =
4350 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4393 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4351 summary->set_in(0, Location::RequiresFpuRegister()); 4394 summary->set_in(0, Location::RequiresFpuRegister());
4352 summary->set_in(1, Location::RegisterLocation(ECX)); 4395 summary->set_in(1, Location::RegisterLocation(ECX));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4403 __ j(NOT_EQUAL, deopt); 4446 __ j(NOT_EQUAL, deopt);
4404 break; 4447 break;
4405 } 4448 }
4406 default: 4449 default:
4407 UNREACHABLE(); 4450 UNREACHABLE();
4408 break; 4451 break;
4409 } 4452 }
4410 __ movq(left, Address(ESP, 0)); 4453 __ movq(left, Address(ESP, 0));
4411 __ addl(ESP, Immediate(2 * kWordSize)); 4454 __ addl(ESP, Immediate(2 * kWordSize));
4412 __ Bind(&done); 4455 __ Bind(&done);
4456 Register tmp = locs()->temp(0).reg();
4457 EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp);
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

Powered by Google App Engine
This is Rietveld 408576698