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

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

Issue 1263513002: VM: Load allocation-top and -end via Thread. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fixed cc tests Created 5 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
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 "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 2033 matching lines...) Expand 10 before | Expand all | Expand 10 after
2044 Label* done) { 2044 Label* done) {
2045 const int kInlineArraySize = 12; // Same as kInlineInstanceSize. 2045 const int kInlineArraySize = 12; // Same as kInlineInstanceSize.
2046 const Register kLengthReg = EDX; 2046 const Register kLengthReg = EDX;
2047 const Register kElemTypeReg = ECX; 2047 const Register kElemTypeReg = ECX;
2048 const intptr_t instance_size = Array::InstanceSize(num_elements); 2048 const intptr_t instance_size = Array::InstanceSize(num_elements);
2049 2049
2050 // Instance in EAX. 2050 // Instance in EAX.
2051 // Object end address in EBX. 2051 // Object end address in EBX.
2052 __ TryAllocateArray(kArrayCid, instance_size, slow_path, Assembler::kFarJump, 2052 __ TryAllocateArray(kArrayCid, instance_size, slow_path, Assembler::kFarJump,
2053 EAX, // instance 2053 EAX, // instance
2054 EBX); // end address 2054 EBX, // end address
2055 EDI); // temp
2055 2056
2056 // Store the type argument field. 2057 // Store the type argument field.
2057 __ InitializeFieldNoBarrier(EAX, 2058 __ InitializeFieldNoBarrier(EAX,
2058 FieldAddress(EAX, Array::type_arguments_offset()), 2059 FieldAddress(EAX, Array::type_arguments_offset()),
2059 kElemTypeReg); 2060 kElemTypeReg);
2060 2061
2061 // Set the length field. 2062 // Set the length field.
2062 __ InitializeFieldNoBarrier(EAX, 2063 __ InitializeFieldNoBarrier(EAX,
2063 FieldAddress(EAX, Array::length_offset()), 2064 FieldAddress(EAX, Array::length_offset()),
2064 kLengthReg); 2065 kLengthReg);
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
2366 __ popl(result_reg); // Pop instantiated type arguments. 2367 __ popl(result_reg); // Pop instantiated type arguments.
2367 __ Bind(&type_arguments_instantiated); 2368 __ Bind(&type_arguments_instantiated);
2368 } 2369 }
2369 2370
2370 2371
2371 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary( 2372 LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
2372 Zone* zone, 2373 Zone* zone,
2373 bool opt) const { 2374 bool opt) const {
2374 ASSERT(opt); 2375 ASSERT(opt);
2375 const intptr_t kNumInputs = 0; 2376 const intptr_t kNumInputs = 0;
2376 const intptr_t kNumTemps = 1; 2377 const intptr_t kNumTemps = 2;
2377 LocationSummary* locs = new(zone) LocationSummary( 2378 LocationSummary* locs = new(zone) LocationSummary(
2378 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 2379 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
2379 locs->set_temp(0, Location::RegisterLocation(ECX)); 2380 locs->set_temp(0, Location::RegisterLocation(ECX));
2381 locs->set_temp(1, Location::RegisterLocation(EDI));
2380 locs->set_out(0, Location::RegisterLocation(EAX)); 2382 locs->set_out(0, Location::RegisterLocation(EAX));
2381 return locs; 2383 return locs;
2382 } 2384 }
2383 2385
2384 2386
2385 class AllocateContextSlowPath : public SlowPathCode { 2387 class AllocateContextSlowPath : public SlowPathCode {
2386 public: 2388 public:
2387 explicit AllocateContextSlowPath( 2389 explicit AllocateContextSlowPath(
2388 AllocateUninitializedContextInstr* instruction) 2390 AllocateUninitializedContextInstr* instruction)
2389 : instruction_(instruction) { } 2391 : instruction_(instruction) { }
(...skipping 20 matching lines...) Expand all
2410 2412
2411 private: 2413 private:
2412 AllocateUninitializedContextInstr* instruction_; 2414 AllocateUninitializedContextInstr* instruction_;
2413 }; 2415 };
2414 2416
2415 2417
2416 void AllocateUninitializedContextInstr::EmitNativeCode( 2418 void AllocateUninitializedContextInstr::EmitNativeCode(
2417 FlowGraphCompiler* compiler) { 2419 FlowGraphCompiler* compiler) {
2418 ASSERT(compiler->is_optimizing()); 2420 ASSERT(compiler->is_optimizing());
2419 Register temp = locs()->temp(0).reg(); 2421 Register temp = locs()->temp(0).reg();
2422 Register temp2 = locs()->temp(1).reg();
2420 Register result = locs()->out(0).reg(); 2423 Register result = locs()->out(0).reg();
2421 // Try allocate the object. 2424 // Try allocate the object.
2422 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this); 2425 AllocateContextSlowPath* slow_path = new AllocateContextSlowPath(this);
2423 compiler->AddSlowPathCode(slow_path); 2426 compiler->AddSlowPathCode(slow_path);
2424 intptr_t instance_size = Context::InstanceSize(num_context_variables()); 2427 intptr_t instance_size = Context::InstanceSize(num_context_variables());
2425 2428
2426 __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(), 2429 __ TryAllocateArray(kContextCid, instance_size, slow_path->entry_label(),
2427 Assembler::kFarJump, 2430 Assembler::kFarJump,
2428 result, // instance 2431 result, // instance
2429 temp); // end address 2432 temp, // end address
2433 temp2); // temp
2430 2434
2431 // Setup up number of context variables field. 2435 // Setup up number of context variables field.
2432 __ movl(FieldAddress(result, Context::num_variables_offset()), 2436 __ movl(FieldAddress(result, Context::num_variables_offset()),
2433 Immediate(num_context_variables())); 2437 Immediate(num_context_variables()));
2434 2438
2435 __ Bind(slow_path->exit_label()); 2439 __ Bind(slow_path->exit_label());
2436 } 2440 }
2437 2441
2438 2442
2439 LocationSummary* AllocateContextInstr::MakeLocationSummary(Zone* zone, 2443 LocationSummary* AllocateContextInstr::MakeLocationSummary(Zone* zone,
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
3317 __ orl(temp, right); 3321 __ orl(temp, right);
3318 __ testl(temp, Immediate(kSmiTagMask)); 3322 __ testl(temp, Immediate(kSmiTagMask));
3319 } 3323 }
3320 __ j(ZERO, deopt); 3324 __ j(ZERO, deopt);
3321 } 3325 }
3322 3326
3323 3327
3324 LocationSummary* BoxInstr::MakeLocationSummary(Zone* zone, 3328 LocationSummary* BoxInstr::MakeLocationSummary(Zone* zone,
3325 bool opt) const { 3329 bool opt) const {
3326 const intptr_t kNumInputs = 1; 3330 const intptr_t kNumInputs = 1;
3327 const intptr_t kNumTemps = 0; 3331 const intptr_t kNumTemps = 1;
3328 LocationSummary* summary = new(zone) LocationSummary( 3332 LocationSummary* summary = new(zone) LocationSummary(
3329 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); 3333 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3330 summary->set_in(0, Location::RequiresFpuRegister()); 3334 summary->set_in(0, Location::RequiresFpuRegister());
3335 summary->set_temp(0, Location::RequiresRegister());
3331 summary->set_out(0, Location::RequiresRegister()); 3336 summary->set_out(0, Location::RequiresRegister());
3332 return summary; 3337 return summary;
3333 } 3338 }
3334 3339
3335 3340
3336 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3341 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3337 Register out_reg = locs()->out(0).reg(); 3342 Register out_reg = locs()->out(0).reg();
3338 XmmRegister value = locs()->in(0).fpu_reg(); 3343 XmmRegister value = locs()->in(0).fpu_reg();
3339 3344
3340 BoxAllocationSlowPath::Allocate( 3345 BoxAllocationSlowPath::Allocate(
3341 compiler, 3346 compiler,
3342 this, 3347 this,
3343 compiler->BoxClassFor(from_representation()), 3348 compiler->BoxClassFor(from_representation()),
3344 out_reg, 3349 out_reg,
3345 kNoRegister); 3350 locs()->temp(0).reg());
3346 3351
3347 switch (from_representation()) { 3352 switch (from_representation()) {
3348 case kUnboxedDouble: 3353 case kUnboxedDouble:
3349 __ movsd(FieldAddress(out_reg, ValueOffset()), value); 3354 __ movsd(FieldAddress(out_reg, ValueOffset()), value);
3350 break; 3355 break;
3351 case kUnboxedFloat32x4: 3356 case kUnboxedFloat32x4:
3352 case kUnboxedFloat64x2: 3357 case kUnboxedFloat64x2:
3353 case kUnboxedInt32x4: 3358 case kUnboxedInt32x4:
3354 __ movups(FieldAddress(out_reg, ValueOffset()), value); 3359 __ movups(FieldAddress(out_reg, ValueOffset()), value);
3355 break; 3360 break;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3483 EmitSmiConversion(compiler); 3488 EmitSmiConversion(compiler);
3484 __ Bind(&done); 3489 __ Bind(&done);
3485 } 3490 }
3486 } 3491 }
3487 } 3492 }
3488 3493
3489 3494
3490 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Zone* zone, 3495 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Zone* zone,
3491 bool opt) const { 3496 bool opt) const {
3492 const intptr_t kNumInputs = 1; 3497 const intptr_t kNumInputs = 1;
3493 const intptr_t kNumTemps = 0; 3498 const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
3494 LocationSummary* summary = new(zone) LocationSummary( 3499 LocationSummary* summary = new(zone) LocationSummary(
3495 zone, kNumInputs, kNumTemps, 3500 zone, kNumInputs, kNumTemps,
3496 ValueFitsSmi() ? LocationSummary::kNoCall 3501 ValueFitsSmi() ? LocationSummary::kNoCall
3497 : LocationSummary::kCallOnSlowPath); 3502 : LocationSummary::kCallOnSlowPath);
3498 const bool needs_writable_input = ValueFitsSmi() || 3503 const bool needs_writable_input = ValueFitsSmi() ||
3499 (from_representation() == kUnboxedUint32); 3504 (from_representation() == kUnboxedUint32);
3500 summary->set_in(0, needs_writable_input ? Location::RequiresRegister() 3505 summary->set_in(0, needs_writable_input ? Location::RequiresRegister()
3501 : Location::WritableRegister()); 3506 : Location::WritableRegister());
3507 if (!ValueFitsSmi()) {
3508 summary->set_temp(0, Location::RequiresRegister());
3509 }
3502 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() 3510 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput()
3503 : Location::RequiresRegister()); 3511 : Location::RequiresRegister());
3504 return summary; 3512 return summary;
3505 } 3513 }
3506 3514
3507 3515
3508 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3516 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3509 const Register value = locs()->in(0).reg(); 3517 const Register value = locs()->in(0).reg();
3510 const Register out = locs()->out(0).reg(); 3518 const Register out = locs()->out(0).reg();
3511 3519
3512 __ MoveRegister(out, value); 3520 __ MoveRegister(out, value);
3513 __ shll(out, Immediate(kSmiTagSize)); 3521 __ shll(out, Immediate(kSmiTagSize));
3514 if (!ValueFitsSmi()) { 3522 if (!ValueFitsSmi()) {
3515 Label done; 3523 Label done;
3516 ASSERT(value != out); 3524 ASSERT(value != out);
3517 if (from_representation() == kUnboxedInt32) { 3525 if (from_representation() == kUnboxedInt32) {
3518 __ j(NO_OVERFLOW, &done); 3526 __ j(NO_OVERFLOW, &done);
3519 } else { 3527 } else {
3520 __ testl(value, Immediate(0xC0000000)); 3528 __ testl(value, Immediate(0xC0000000));
3521 __ j(ZERO, &done); 3529 __ j(ZERO, &done);
3522 } 3530 }
3523 3531
3524 // Allocate a mint. 3532 // Allocate a mint.
3525 // Value input is writable register and has to be manually preserved 3533 // Value input is writable register and has to be manually preserved
3526 // on the slow path. 3534 // on the slow path.
3527 locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32); 3535 locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32);
3528 BoxAllocationSlowPath::Allocate( 3536 BoxAllocationSlowPath::Allocate(
3529 compiler, this, compiler->mint_class(), out, kNoRegister); 3537 compiler, this, compiler->mint_class(), out, locs()->temp(0).reg());
3530 __ movl(FieldAddress(out, Mint::value_offset()), value); 3538 __ movl(FieldAddress(out, Mint::value_offset()), value);
3531 if (from_representation() == kUnboxedInt32) { 3539 if (from_representation() == kUnboxedInt32) {
3532 __ sarl(value, Immediate(31)); // Sign extend. 3540 __ sarl(value, Immediate(31)); // Sign extend.
3533 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value); 3541 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value);
3534 } else { 3542 } else {
3535 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), 3543 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize),
3536 Immediate(0)); 3544 Immediate(0));
3537 } 3545 }
3538 __ Bind(&done); 3546 __ Bind(&done);
3539 } 3547 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3594 // 3. Restore lower half if result is a smi. 3602 // 3. Restore lower half if result is a smi.
3595 __ subl(value_lo, Immediate(0x40000000)); 3603 __ subl(value_lo, Immediate(0x40000000));
3596 __ movl(out_reg, value_lo); 3604 __ movl(out_reg, value_lo);
3597 __ SmiTag(out_reg); 3605 __ SmiTag(out_reg);
3598 __ jmp(&done); 3606 __ jmp(&done);
3599 __ Bind(&not_smi); 3607 __ Bind(&not_smi);
3600 // 3. Restore lower half of input before using it. 3608 // 3. Restore lower half of input before using it.
3601 __ subl(value_lo, Immediate(0x40000000)); 3609 __ subl(value_lo, Immediate(0x40000000));
3602 3610
3603 BoxAllocationSlowPath::Allocate( 3611 BoxAllocationSlowPath::Allocate(
3604 compiler, this, compiler->mint_class(), out_reg, kNoRegister); 3612 compiler, this, compiler->mint_class(), out_reg, locs()->temp(0).reg());
3605 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo); 3613 __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo);
3606 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi); 3614 __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi);
3607 __ Bind(&done); 3615 __ Bind(&done);
3608 } 3616 }
3609 3617
3610 3618
3611 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone, 3619 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Zone* zone,
3612 bool opt) const { 3620 bool opt) const {
3613 const intptr_t value_cid = value()->Type()->ToCid(); 3621 const intptr_t value_cid = value()->Type()->ToCid();
3614 const intptr_t kNumInputs = 1; 3622 const intptr_t kNumInputs = 1;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3701 out_of_range); 3709 out_of_range);
3702 __ Bind(&done); 3710 __ Bind(&done);
3703 } 3711 }
3704 } 3712 }
3705 3713
3706 3714
3707 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Zone* zone, 3715 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Zone* zone,
3708 bool opt) const { 3716 bool opt) const {
3709 const bool might_box = (representation() == kTagged) && !can_pack_into_smi(); 3717 const bool might_box = (representation() == kTagged) && !can_pack_into_smi();
3710 const intptr_t kNumInputs = 2; 3718 const intptr_t kNumInputs = 2;
3711 const intptr_t kNumTemps = might_box ? 1 : 0; 3719 const intptr_t kNumTemps = might_box ? 2 : 0;
3712 LocationSummary* summary = new(zone) LocationSummary( 3720 LocationSummary* summary = new(zone) LocationSummary(
3713 zone, kNumInputs, kNumTemps, 3721 zone, kNumInputs, kNumTemps,
3714 might_box ? LocationSummary::kCallOnSlowPath : LocationSummary::kNoCall); 3722 might_box ? LocationSummary::kCallOnSlowPath : LocationSummary::kNoCall);
3715 summary->set_in(0, Location::RequiresRegister()); 3723 summary->set_in(0, Location::RequiresRegister());
3716 // The smi index is either untagged (element size == 1), or it is left smi 3724 // The smi index is either untagged (element size == 1), or it is left smi
3717 // tagged (for all element sizes > 1). 3725 // tagged (for all element sizes > 1).
3718 summary->set_in(1, (index_scale() == 1) ? Location::WritableRegister() 3726 summary->set_in(1, (index_scale() == 1) ? Location::WritableRegister()
3719 : Location::RequiresRegister()); 3727 : Location::RequiresRegister());
3720 if (might_box) { 3728 if (might_box) {
3721 summary->set_temp(0, Location::RequiresRegister()); 3729 summary->set_temp(0, Location::RequiresRegister());
3730 summary->set_temp(1, Location::RequiresRegister());
3722 } 3731 }
3723 3732
3724 if (representation() == kUnboxedMint) { 3733 if (representation() == kUnboxedMint) {
3725 summary->set_out(0, Location::Pair(Location::RequiresRegister(), 3734 summary->set_out(0, Location::Pair(Location::RequiresRegister(),
3726 Location::RequiresRegister())); 3735 Location::RequiresRegister()));
3727 } else { 3736 } else {
3728 ASSERT(representation() == kTagged); 3737 ASSERT(representation() == kTagged);
3729 summary->set_out(0, Location::RequiresRegister()); 3738 summary->set_out(0, Location::RequiresRegister());
3730 } 3739 }
3731 3740
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3791 break; 3800 break;
3792 default: 3801 default:
3793 UNREACHABLE(); 3802 UNREACHABLE();
3794 break; 3803 break;
3795 } 3804 }
3796 if (can_pack_into_smi()) { 3805 if (can_pack_into_smi()) {
3797 __ SmiTag(result); 3806 __ SmiTag(result);
3798 } else { 3807 } else {
3799 // If the value cannot fit in a smi then allocate a mint box for it. 3808 // If the value cannot fit in a smi then allocate a mint box for it.
3800 Register temp = locs()->temp(0).reg(); 3809 Register temp = locs()->temp(0).reg();
3810 Register temp2 = locs()->temp(1).reg();
3801 // Temp register needs to be manually preserved on allocation slow-path. 3811 // Temp register needs to be manually preserved on allocation slow-path.
3802 locs()->live_registers()->Add(locs()->temp(0), kUnboxedInt32); 3812 locs()->live_registers()->Add(locs()->temp(0), kUnboxedInt32);
3803 3813
3804 ASSERT(temp != result); 3814 ASSERT(temp != result);
3805 __ MoveRegister(temp, result); 3815 __ MoveRegister(temp, result);
3806 __ SmiTag(result); 3816 __ SmiTag(result);
3807 3817
3808 Label done; 3818 Label done;
3809 __ testl(temp, Immediate(0xC0000000)); 3819 __ testl(temp, Immediate(0xC0000000));
3810 __ j(ZERO, &done); 3820 __ j(ZERO, &done);
3811 BoxAllocationSlowPath::Allocate( 3821 BoxAllocationSlowPath::Allocate(
3812 compiler, this, compiler->mint_class(), result, kNoRegister); 3822 compiler, this, compiler->mint_class(), result, temp2);
3813 __ movl(FieldAddress(result, Mint::value_offset()), temp); 3823 __ movl(FieldAddress(result, Mint::value_offset()), temp);
3814 __ movl(FieldAddress(result, Mint::value_offset() + kWordSize), 3824 __ movl(FieldAddress(result, Mint::value_offset() + kWordSize),
3815 Immediate(0)); 3825 Immediate(0));
3816 __ Bind(&done); 3826 __ Bind(&done);
3817 } 3827 }
3818 } 3828 }
3819 } 3829 }
3820 3830
3821 3831
3822 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Zone* zone, 3832 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Zone* zone,
(...skipping 3023 matching lines...) Expand 10 before | Expand all | Expand 10 after
6846 __ Drop(1); 6856 __ Drop(1);
6847 __ popl(result); 6857 __ popl(result);
6848 } 6858 }
6849 6859
6850 6860
6851 } // namespace dart 6861 } // namespace dart
6852 6862
6853 #undef __ 6863 #undef __
6854 6864
6855 #endif // defined TARGET_ARCH_IA32 6865 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698