| 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_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 13 matching lines...) Expand all Loading... |
| 24 namespace dart { | 24 namespace dart { |
| 25 | 25 |
| 26 DECLARE_FLAG(bool, code_comments); | 26 DECLARE_FLAG(bool, code_comments); |
| 27 DECLARE_FLAG(bool, enable_type_checks); | 27 DECLARE_FLAG(bool, enable_type_checks); |
| 28 DECLARE_FLAG(bool, intrinsify); | 28 DECLARE_FLAG(bool, intrinsify); |
| 29 DECLARE_FLAG(bool, propagate_ic_data); | 29 DECLARE_FLAG(bool, propagate_ic_data); |
| 30 DECLARE_FLAG(bool, report_usage_count); | 30 DECLARE_FLAG(bool, report_usage_count); |
| 31 DECLARE_FLAG(int, optimization_counter_threshold); | 31 DECLARE_FLAG(int, optimization_counter_threshold); |
| 32 DECLARE_FLAG(bool, use_cha); | 32 DECLARE_FLAG(bool, use_cha); |
| 33 DECLARE_FLAG(bool, use_osr); | 33 DECLARE_FLAG(bool, use_osr); |
| 34 | 34 DEFINE_FLAG(bool, enable_simd_inline, true, |
| 35 "Enable inlining of SIMD related method calls."); |
| 35 | 36 |
| 36 // Assign locations to incoming arguments, i.e., values pushed above spill slots | 37 // Assign locations to incoming arguments, i.e., values pushed above spill slots |
| 37 // with PushArgument. Recursively allocates from outermost to innermost | 38 // with PushArgument. Recursively allocates from outermost to innermost |
| 38 // environment. | 39 // environment. |
| 39 void CompilerDeoptInfo::AllocateIncomingParametersRecursive( | 40 void CompilerDeoptInfo::AllocateIncomingParametersRecursive( |
| 40 Environment* env, | 41 Environment* env, |
| 41 intptr_t* stack_height) { | 42 intptr_t* stack_height) { |
| 42 if (env == NULL) return; | 43 if (env == NULL) return; |
| 43 AllocateIncomingParametersRecursive(env->outer(), stack_height); | 44 AllocateIncomingParametersRecursive(env->outer(), stack_height); |
| 44 for (Environment::ShallowIterator it(env); !it.Done(); it.Advance()) { | 45 for (Environment::ShallowIterator it(env); !it.Done(); it.Advance()) { |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 pending_deoptimization_env_); | 449 pending_deoptimization_env_); |
| 449 info->set_pc_offset(assembler()->CodeSize()); | 450 info->set_pc_offset(assembler()->CodeSize()); |
| 450 deopt_infos_.Add(info); | 451 deopt_infos_.Add(info); |
| 451 } | 452 } |
| 452 | 453 |
| 453 | 454 |
| 454 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters | 455 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters |
| 455 // and FlowGraphCompiler::SlowPathEnvironmentFor. | 456 // and FlowGraphCompiler::SlowPathEnvironmentFor. |
| 456 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { | 457 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { |
| 457 if (is_optimizing()) { | 458 if (is_optimizing()) { |
| 459 RegisterSet* registers = locs->live_registers(); |
| 460 ASSERT(registers != NULL); |
| 461 const intptr_t kFpuRegisterSpillFactor = |
| 462 kFpuRegisterSize / kWordSize; |
| 463 const intptr_t live_registers_size = registers->CpuRegisterCount() + |
| 464 (registers->FpuRegisterCount() * kFpuRegisterSpillFactor); |
| 458 BitmapBuilder* bitmap = locs->stack_bitmap(); | 465 BitmapBuilder* bitmap = locs->stack_bitmap(); |
| 459 ASSERT(bitmap != NULL); | 466 ASSERT(bitmap != NULL); |
| 460 ASSERT(bitmap->Length() <= StackSize()); | 467 // An instruction may have two safepoints in deferred code. The |
| 461 // Pad the bitmap out to describe all the spill slots. | 468 // call to RecordSafepoint has the side-effect of appending the live |
| 469 // registers to the bitmap. This is why the second call to RecordSafepoint |
| 470 // with the same instruction (and same location summary) sees a bitmap that |
| 471 // is larger that StackSize(). It will never be larger than StackSize() + |
| 472 // live_registers_size. |
| 473 ASSERT(bitmap->Length() <= (StackSize() + live_registers_size)); |
| 474 // The first safepoint will grow the bitmap to be the size of StackSize() |
| 475 // but the second safepoint will truncate the bitmap and append the |
| 476 // live registers to it again. The bitmap produced by both calls will |
| 477 // be the same. |
| 462 bitmap->SetLength(StackSize()); | 478 bitmap->SetLength(StackSize()); |
| 463 | 479 |
| 464 // Mark the bits in the stack map in the same order we push registers in | 480 // Mark the bits in the stack map in the same order we push registers in |
| 465 // slow path code (see FlowGraphCompiler::SaveLiveRegisters). | 481 // slow path code (see FlowGraphCompiler::SaveLiveRegisters). |
| 466 // | 482 // |
| 467 // Slow path code can have registers at the safepoint. | 483 // Slow path code can have registers at the safepoint. |
| 468 if (!locs->always_calls()) { | 484 if (!locs->always_calls()) { |
| 469 RegisterSet* regs = locs->live_registers(); | 485 RegisterSet* regs = locs->live_registers(); |
| 470 if (regs->FpuRegisterCount() > 0) { | 486 if (regs->FpuRegisterCount() > 0) { |
| 471 // Denote FPU registers with 0 bits in the stackmap. Based on the | 487 // Denote FPU registers with 0 bits in the stackmap. Based on the |
| 472 // assumption that there are normally few live FPU registers, this | 488 // assumption that there are normally few live FPU registers, this |
| 473 // encoding is simpler and roughly as compact as storing a separate | 489 // encoding is simpler and roughly as compact as storing a separate |
| 474 // count of FPU registers. | 490 // count of FPU registers. |
| 475 // | 491 // |
| 476 // FPU registers have the highest register number at the highest | 492 // FPU registers have the highest register number at the highest |
| 477 // address (i.e., first in the stackmap). | 493 // address (i.e., first in the stackmap). |
| 478 const intptr_t kFpuRegisterSpillFactor = | |
| 479 kFpuRegisterSize / kWordSize; | |
| 480 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) { | 494 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) { |
| 481 FpuRegister reg = static_cast<FpuRegister>(i); | 495 FpuRegister reg = static_cast<FpuRegister>(i); |
| 482 if (regs->ContainsFpuRegister(reg)) { | 496 if (regs->ContainsFpuRegister(reg)) { |
| 483 for (intptr_t j = 0; j < kFpuRegisterSpillFactor; ++j) { | 497 for (intptr_t j = 0; j < kFpuRegisterSpillFactor; ++j) { |
| 484 bitmap->Set(bitmap->Length(), false); | 498 bitmap->Set(bitmap->Length(), false); |
| 485 } | 499 } |
| 486 } | 500 } |
| 487 } | 501 } |
| 488 } | 502 } |
| 489 // General purpose registers have the lowest register number at the | 503 // General purpose registers have the lowest register number at the |
| (...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 | 1280 |
| 1267 for (int i = 0; i < len; i++) { | 1281 for (int i = 0; i < len; i++) { |
| 1268 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), | 1282 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), |
| 1269 &Function::ZoneHandle(ic_data.GetTargetAt(i)), | 1283 &Function::ZoneHandle(ic_data.GetTargetAt(i)), |
| 1270 ic_data.GetCountAt(i))); | 1284 ic_data.GetCountAt(i))); |
| 1271 } | 1285 } |
| 1272 sorted->Sort(HighestCountFirst); | 1286 sorted->Sort(HighestCountFirst); |
| 1273 } | 1287 } |
| 1274 | 1288 |
| 1275 } // namespace dart | 1289 } // namespace dart |
| OLD | NEW |