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

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

Issue 26823006: Record a correct deoptimization environment for slow-path code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Use an environment value's representation to decide its size. Created 7 years, 2 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_XXX. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX.
6 6
7 #include "vm/flow_graph_compiler.h" 7 #include "vm/flow_graph_compiler.h"
8 8
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 ASSERT(is_optimizing()); 390 ASSERT(is_optimizing());
391 CompilerDeoptInfo* info = 391 CompilerDeoptInfo* info =
392 new CompilerDeoptInfo(deopt_id, 392 new CompilerDeoptInfo(deopt_id,
393 kDeoptAtCall, 393 kDeoptAtCall,
394 pending_deoptimization_env_); 394 pending_deoptimization_env_);
395 info->set_pc_offset(assembler()->CodeSize()); 395 info->set_pc_offset(assembler()->CodeSize());
396 deopt_infos_.Add(info); 396 deopt_infos_.Add(info);
397 } 397 }
398 398
399 399
400 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters
401 // and FlowGraphCompiler::SlowPathEnvironmentFor.
400 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { 402 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) {
401 if (is_optimizing()) { 403 if (is_optimizing()) {
402 BitmapBuilder* bitmap = locs->stack_bitmap(); 404 BitmapBuilder* bitmap = locs->stack_bitmap();
403 ASSERT(bitmap != NULL); 405 ASSERT(bitmap != NULL);
404 ASSERT(bitmap->Length() <= StackSize()); 406 ASSERT(bitmap->Length() <= StackSize());
405 // Pad the bitmap out to describe all the spill slots. 407 // Pad the bitmap out to describe all the spill slots.
406 bitmap->SetLength(StackSize()); 408 bitmap->SetLength(StackSize());
407 409
408 // Mark the bits in the stack map in the same order we push registers in 410 // Mark the bits in the stack map in the same order we push registers in
409 // slow path code (see FlowGraphCompiler::SaveLiveRegisters). 411 // slow path code (see FlowGraphCompiler::SaveLiveRegisters).
410 // 412 //
411 // Slow path code can have registers at the safepoint. 413 // Slow path code can have registers at the safepoint.
412 if (!locs->always_calls()) { 414 if (!locs->always_calls()) {
413 RegisterSet* regs = locs->live_registers(); 415 RegisterSet* regs = locs->live_registers();
414 if (regs->fpu_regs_count() > 0) { 416 if (regs->FpuRegisterCount() > 0) {
415 // Denote FPU registers with 0 bits in the stackmap. Based on the 417 // Denote FPU registers with 0 bits in the stackmap. Based on the
416 // assumption that there are normally few live FPU registers, this 418 // assumption that there are normally few live FPU registers, this
417 // encoding is simpler and roughly as compact as storing a separate 419 // encoding is simpler and roughly as compact as storing a separate
418 // count of FPU registers. 420 // count of FPU registers.
419 // 421 //
420 // FPU registers have the highest register number at the highest 422 // FPU registers have the highest register number at the highest
421 // address (i.e., first in the stackmap). 423 // address (i.e., first in the stackmap).
422 const intptr_t kFpuRegisterSpillFactor = 424 const intptr_t kFpuRegisterSpillFactor =
423 kFpuRegisterSize / kWordSize; 425 kFpuRegisterSize / kWordSize;
424 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) { 426 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) {
(...skipping 16 matching lines...) Expand all
441 } 443 }
442 444
443 intptr_t register_bit_count = bitmap->Length() - StackSize(); 445 intptr_t register_bit_count = bitmap->Length() - StackSize();
444 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), 446 stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
445 bitmap, 447 bitmap,
446 register_bit_count); 448 register_bit_count);
447 } 449 }
448 } 450 }
449 451
450 452
453 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and
454 // FlowGraphCompiler::SaveLiveRegisters.
455 Environment* FlowGraphCompiler::SlowPathEnvironmentFor(
456 Instruction* instruction) {
457 if (instruction->env() == NULL) return NULL;
458
459 Environment* env = instruction->env()->DeepCopy();
460 // 1. Iterate the registers in the order they will be spilled to compute
461 // the slots they will be spilled to.
462 intptr_t next_slot = StackSize();
463 RegisterSet* regs = instruction->locs()->live_registers();
464 intptr_t fpu_reg_slots[kNumberOfFpuRegisters];
465 intptr_t cpu_reg_slots[kNumberOfCpuRegisters];
466 const intptr_t kFpuRegisterSpillFactor = kFpuRegisterSize / kWordSize;
467 // FPU registers are spilled first from highest to lowest register number.
468 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) {
469 FpuRegister reg = static_cast<FpuRegister>(i);
470 if (regs->ContainsFpuRegister(reg)) {
471 // We use the lowest address (thus highest index) to identify a
472 // multi-word spill slot.
473 next_slot += kFpuRegisterSpillFactor;
474 fpu_reg_slots[i] = (next_slot - 1);
475 } else {
476 fpu_reg_slots[i] = -1;
477 }
478 }
479 // General purpose registers are spilled from lowest to highest register
480 // number.
481 for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
482 Register reg = static_cast<Register>(i);
483 if (regs->ContainsRegister(reg)) {
484 cpu_reg_slots[i] = next_slot++;
485 } else {
486 cpu_reg_slots[i] = -1;
487 }
488 }
489
490 // 2. Iterate the environment and replace register locations with the
491 // corresponding spill slot locations.
492 for (Environment::DeepIterator it(env); !it.Done(); it.Advance()) {
493 Location loc = it.CurrentLocation();
494 if (loc.IsRegister()) {
495 intptr_t index = cpu_reg_slots[loc.reg()];
496 ASSERT(index >= 0);
Florian Schneider 2013/10/17 14:38:52 Shouldn't this be even stronger? ASSERT(index >=
497 it.SetCurrentLocation(Location::StackSlot(index));
498 } else if (loc.IsFpuRegister()) {
499 assembler()->Comment("You betcha!");
Kevin Millikin (Google) 2013/10/14 16:12:52 Ignore this.
srdjan 2013/12/03 22:42:10 But it was submitted. Can we replace it with somet
500 intptr_t index = fpu_reg_slots[loc.fpu_reg()];
501 ASSERT(index >= 0);
Florian Schneider 2013/10/17 14:38:52 ASSERT(index >= 0 && index >= StackSize());
502 Value* value = it.CurrentValue();
503 switch (value->definition()->representation()) {
504 case kUnboxedDouble:
505 case kUnboxedMint:
506 it.SetCurrentLocation(Location::DoubleStackSlot(index));
Kevin Millikin (Google) 2013/10/14 16:12:52 As discussed offline, I'm not sure that this index
507 break;
508 case kUnboxedFloat32x4:
509 case kUnboxedUint32x4:
510 it.SetCurrentLocation(Location::QuadStackSlot(index));
Florian Schneider 2013/10/17 14:38:52 Try to also have a test case for the quad-word cas
511 break;
512 default:
513 UNREACHABLE();
514 }
515 }
516 }
517
518 return env;
519 }
520
521
451 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, 522 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id,
452 DeoptReasonId reason) { 523 DeoptReasonId reason) {
453 ASSERT(is_optimizing_); 524 ASSERT(is_optimizing_);
454 CompilerDeoptInfoWithStub* stub = 525 CompilerDeoptInfoWithStub* stub =
455 new CompilerDeoptInfoWithStub(deopt_id, 526 new CompilerDeoptInfoWithStub(deopt_id,
456 reason, 527 reason,
457 pending_deoptimization_env_); 528 pending_deoptimization_env_);
458 deopt_infos_.Add(stub); 529 deopt_infos_.Add(stub);
459 return stub->entry_label(); 530 return stub->entry_label();
460 } 531 }
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 1205
1135 for (int i = 0; i < len; i++) { 1206 for (int i = 0; i < len; i++) {
1136 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), 1207 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i),
1137 &Function::ZoneHandle(ic_data.GetTargetAt(i)), 1208 &Function::ZoneHandle(ic_data.GetTargetAt(i)),
1138 ic_data.GetCountAt(i))); 1209 ic_data.GetCountAt(i)));
1139 } 1210 }
1140 sorted->Sort(HighestCountFirst); 1211 sorted->Sort(HighestCountFirst);
1141 } 1212 }
1142 1213
1143 } // namespace dart 1214 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698