| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/register-allocator.h" | 5 #include "src/compiler/register-allocator.h" |
| 6 | 6 |
| 7 #include "src/compiler/linkage.h" | 7 #include "src/compiler/linkage.h" |
| 8 #include "src/hydrogen.h" | 8 #include "src/hydrogen.h" |
| 9 #include "src/string-stream.h" | 9 #include "src/string-stream.h" |
| 10 | 10 |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 if (a == NULL || a->start().Value() > other->End().Value()) break; | 492 if (a == NULL || a->start().Value() > other->End().Value()) break; |
| 493 AdvanceLastProcessedMarker(a, advance_last_processed_up_to); | 493 AdvanceLastProcessedMarker(a, advance_last_processed_up_to); |
| 494 } else { | 494 } else { |
| 495 b = b->next(); | 495 b = b->next(); |
| 496 } | 496 } |
| 497 } | 497 } |
| 498 return LifetimePosition::Invalid(); | 498 return LifetimePosition::Invalid(); |
| 499 } | 499 } |
| 500 | 500 |
| 501 | 501 |
| 502 RegisterAllocator::RegisterAllocator(InstructionSequence* code) | 502 RegisterAllocator::RegisterAllocator(Frame* frame, CompilationInfo* info, |
| 503 InstructionSequence* code) |
| 503 : zone_(code->isolate()), | 504 : zone_(code->isolate()), |
| 505 frame_(frame), |
| 506 info_(info), |
| 504 code_(code), | 507 code_(code), |
| 505 live_in_sets_(code->BasicBlockCount(), zone()), | 508 live_in_sets_(code->InstructionBlockCount(), zone()), |
| 506 live_ranges_(code->VirtualRegisterCount() * 2, zone()), | 509 live_ranges_(code->VirtualRegisterCount() * 2, zone()), |
| 507 fixed_live_ranges_(NULL), | 510 fixed_live_ranges_(NULL), |
| 508 fixed_double_live_ranges_(NULL), | 511 fixed_double_live_ranges_(NULL), |
| 509 unhandled_live_ranges_(code->VirtualRegisterCount() * 2, zone()), | 512 unhandled_live_ranges_(code->VirtualRegisterCount() * 2, zone()), |
| 510 active_live_ranges_(8, zone()), | 513 active_live_ranges_(8, zone()), |
| 511 inactive_live_ranges_(8, zone()), | 514 inactive_live_ranges_(8, zone()), |
| 512 reusable_slots_(8, zone()), | 515 reusable_slots_(8, zone()), |
| 513 mode_(UNALLOCATED_REGISTERS), | 516 mode_(UNALLOCATED_REGISTERS), |
| 514 num_registers_(-1), | 517 num_registers_(-1), |
| 515 allocation_ok_(true) {} | 518 allocation_ok_(true) {} |
| 516 | 519 |
| 517 | 520 |
| 518 void RegisterAllocator::InitializeLivenessAnalysis() { | 521 void RegisterAllocator::InitializeLivenessAnalysis() { |
| 519 // Initialize the live_in sets for each block to NULL. | 522 // Initialize the live_in sets for each block to NULL. |
| 520 int block_count = code()->BasicBlockCount(); | 523 int block_count = code()->InstructionBlockCount(); |
| 521 live_in_sets_.Initialize(block_count, zone()); | 524 live_in_sets_.Initialize(block_count, zone()); |
| 522 live_in_sets_.AddBlock(NULL, block_count, zone()); | 525 live_in_sets_.AddBlock(NULL, block_count, zone()); |
| 523 } | 526 } |
| 524 | 527 |
| 525 | 528 |
| 526 BitVector* RegisterAllocator::ComputeLiveOut(const InstructionBlock* block) { | 529 BitVector* RegisterAllocator::ComputeLiveOut(const InstructionBlock* block) { |
| 527 // Compute live out for the given block, except not including backward | 530 // Compute live out for the given block, except not including backward |
| 528 // successor edges. | 531 // successor edges. |
| 529 BitVector* live_out = | 532 BitVector* live_out = |
| 530 new (zone()) BitVector(code()->VirtualRegisterCount(), zone()); | 533 new (zone()) BitVector(code()->VirtualRegisterCount(), zone()); |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 if (!AllocationOk()) return false; | 1103 if (!AllocationOk()) return false; |
| 1101 ResolvePhis(); | 1104 ResolvePhis(); |
| 1102 BuildLiveRanges(); | 1105 BuildLiveRanges(); |
| 1103 AllocateGeneralRegisters(); | 1106 AllocateGeneralRegisters(); |
| 1104 if (!AllocationOk()) return false; | 1107 if (!AllocationOk()) return false; |
| 1105 AllocateDoubleRegisters(); | 1108 AllocateDoubleRegisters(); |
| 1106 if (!AllocationOk()) return false; | 1109 if (!AllocationOk()) return false; |
| 1107 PopulatePointerMaps(); | 1110 PopulatePointerMaps(); |
| 1108 ConnectRanges(); | 1111 ConnectRanges(); |
| 1109 ResolveControlFlow(); | 1112 ResolveControlFlow(); |
| 1110 code()->frame()->SetAllocatedRegisters(assigned_registers_); | 1113 frame()->SetAllocatedRegisters(assigned_registers_); |
| 1111 code()->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_); | 1114 frame()->SetAllocatedDoubleRegisters(assigned_double_registers_); |
| 1112 return true; | 1115 return true; |
| 1113 } | 1116 } |
| 1114 | 1117 |
| 1115 | 1118 |
| 1116 void RegisterAllocator::MeetRegisterConstraints() { | 1119 void RegisterAllocator::MeetRegisterConstraints() { |
| 1117 RegisterAllocatorPhase phase("L_Register constraints", this); | 1120 RegisterAllocatorPhase phase("L_Register constraints", this); |
| 1118 for (int i = 0; i < code()->BasicBlockCount(); ++i) { | 1121 for (int i = 0; i < code()->InstructionBlockCount(); ++i) { |
| 1119 MeetRegisterConstraints( | 1122 MeetRegisterConstraints( |
| 1120 code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(i))); | 1123 code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(i))); |
| 1121 if (!AllocationOk()) return; | 1124 if (!AllocationOk()) return; |
| 1122 } | 1125 } |
| 1123 } | 1126 } |
| 1124 | 1127 |
| 1125 | 1128 |
| 1126 void RegisterAllocator::ResolvePhis() { | 1129 void RegisterAllocator::ResolvePhis() { |
| 1127 RegisterAllocatorPhase phase("L_Resolve phis", this); | 1130 RegisterAllocatorPhase phase("L_Resolve phis", this); |
| 1128 | 1131 |
| 1129 // Process the blocks in reverse order. | 1132 // Process the blocks in reverse order. |
| 1130 for (int i = code()->BasicBlockCount() - 1; i >= 0; --i) { | 1133 for (int i = code()->InstructionBlockCount() - 1; i >= 0; --i) { |
| 1131 ResolvePhis(code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(i))); | 1134 ResolvePhis(code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(i))); |
| 1132 } | 1135 } |
| 1133 } | 1136 } |
| 1134 | 1137 |
| 1135 | 1138 |
| 1136 void RegisterAllocator::ResolveControlFlow(LiveRange* range, | 1139 void RegisterAllocator::ResolveControlFlow(LiveRange* range, |
| 1137 const InstructionBlock* block, | 1140 const InstructionBlock* block, |
| 1138 const InstructionBlock* pred) { | 1141 const InstructionBlock* pred) { |
| 1139 LifetimePosition pred_end = | 1142 LifetimePosition pred_end = |
| 1140 LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); | 1143 LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 | 1244 |
| 1242 bool RegisterAllocator::CanEagerlyResolveControlFlow( | 1245 bool RegisterAllocator::CanEagerlyResolveControlFlow( |
| 1243 const InstructionBlock* block) const { | 1246 const InstructionBlock* block) const { |
| 1244 if (block->PredecessorCount() != 1) return false; | 1247 if (block->PredecessorCount() != 1) return false; |
| 1245 return block->predecessors()[0].IsNext(block->rpo_number()); | 1248 return block->predecessors()[0].IsNext(block->rpo_number()); |
| 1246 } | 1249 } |
| 1247 | 1250 |
| 1248 | 1251 |
| 1249 void RegisterAllocator::ResolveControlFlow() { | 1252 void RegisterAllocator::ResolveControlFlow() { |
| 1250 RegisterAllocatorPhase phase("L_Resolve control flow", this); | 1253 RegisterAllocatorPhase phase("L_Resolve control flow", this); |
| 1251 for (int block_id = 1; block_id < code()->BasicBlockCount(); ++block_id) { | 1254 for (int block_id = 1; block_id < code()->InstructionBlockCount(); |
| 1255 ++block_id) { |
| 1252 const InstructionBlock* block = | 1256 const InstructionBlock* block = |
| 1253 code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id)); | 1257 code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id)); |
| 1254 if (CanEagerlyResolveControlFlow(block)) continue; | 1258 if (CanEagerlyResolveControlFlow(block)) continue; |
| 1255 BitVector* live = live_in_sets_[block->rpo_number().ToInt()]; | 1259 BitVector* live = live_in_sets_[block->rpo_number().ToInt()]; |
| 1256 BitVector::Iterator iterator(live); | 1260 BitVector::Iterator iterator(live); |
| 1257 while (!iterator.Done()) { | 1261 while (!iterator.Done()) { |
| 1258 int operand_index = iterator.Current(); | 1262 int operand_index = iterator.Current(); |
| 1259 for (auto pred : block->predecessors()) { | 1263 for (auto pred : block->predecessors()) { |
| 1260 const InstructionBlock* cur = code()->InstructionBlockAt(pred); | 1264 const InstructionBlock* cur = code()->InstructionBlockAt(pred); |
| 1261 LiveRange* cur_range = LiveRangeFor(operand_index); | 1265 LiveRange* cur_range = LiveRangeFor(operand_index); |
| 1262 ResolveControlFlow(cur_range, block, cur); | 1266 ResolveControlFlow(cur_range, block, cur); |
| 1263 } | 1267 } |
| 1264 iterator.Advance(); | 1268 iterator.Advance(); |
| 1265 } | 1269 } |
| 1266 } | 1270 } |
| 1267 } | 1271 } |
| 1268 | 1272 |
| 1269 | 1273 |
| 1270 void RegisterAllocator::BuildLiveRanges() { | 1274 void RegisterAllocator::BuildLiveRanges() { |
| 1271 RegisterAllocatorPhase phase("L_Build live ranges", this); | 1275 RegisterAllocatorPhase phase("L_Build live ranges", this); |
| 1272 InitializeLivenessAnalysis(); | 1276 InitializeLivenessAnalysis(); |
| 1273 // Process the blocks in reverse order. | 1277 // Process the blocks in reverse order. |
| 1274 for (int block_id = code()->BasicBlockCount() - 1; block_id >= 0; | 1278 for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0; |
| 1275 --block_id) { | 1279 --block_id) { |
| 1276 const InstructionBlock* block = | 1280 const InstructionBlock* block = |
| 1277 code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id)); | 1281 code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id)); |
| 1278 BitVector* live = ComputeLiveOut(block); | 1282 BitVector* live = ComputeLiveOut(block); |
| 1279 // Initially consider all live_out values live for the entire block. We | 1283 // Initially consider all live_out values live for the entire block. We |
| 1280 // will shorten these intervals if necessary. | 1284 // will shorten these intervals if necessary. |
| 1281 AddInitialIntervals(block, live); | 1285 AddInitialIntervals(block, live); |
| 1282 | 1286 |
| 1283 // Process the instructions in reverse order, generating and killing | 1287 // Process the instructions in reverse order, generating and killing |
| 1284 // live values. | 1288 // live values. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 if (block_id == 0) { | 1351 if (block_id == 0) { |
| 1348 BitVector::Iterator iterator(live); | 1352 BitVector::Iterator iterator(live); |
| 1349 bool found = false; | 1353 bool found = false; |
| 1350 while (!iterator.Done()) { | 1354 while (!iterator.Done()) { |
| 1351 found = true; | 1355 found = true; |
| 1352 int operand_index = iterator.Current(); | 1356 int operand_index = iterator.Current(); |
| 1353 PrintF("Register allocator error: live v%d reached first block.\n", | 1357 PrintF("Register allocator error: live v%d reached first block.\n", |
| 1354 operand_index); | 1358 operand_index); |
| 1355 LiveRange* range = LiveRangeFor(operand_index); | 1359 LiveRange* range = LiveRangeFor(operand_index); |
| 1356 PrintF(" (first use is at %d)\n", range->first_pos()->pos().Value()); | 1360 PrintF(" (first use is at %d)\n", range->first_pos()->pos().Value()); |
| 1357 CompilationInfo* info = code()->linkage()->info(); | 1361 CompilationInfo* info = this->info(); |
| 1358 if (info->IsStub()) { | 1362 if (info->IsStub()) { |
| 1359 if (info->code_stub() == NULL) { | 1363 if (info->code_stub() == NULL) { |
| 1360 PrintF("\n"); | 1364 PrintF("\n"); |
| 1361 } else { | 1365 } else { |
| 1362 CodeStub::Major major_key = info->code_stub()->MajorKey(); | 1366 CodeStub::Major major_key = info->code_stub()->MajorKey(); |
| 1363 PrintF(" (function: %s)\n", CodeStub::MajorName(major_key, false)); | 1367 PrintF(" (function: %s)\n", CodeStub::MajorName(major_key, false)); |
| 1364 } | 1368 } |
| 1365 } else { | 1369 } else { |
| 1366 DCHECK(info->IsOptimizing()); | 1370 DCHECK(info->IsOptimizing()); |
| 1367 AllowHandleDereference allow_deref; | 1371 AllowHandleDereference allow_deref; |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1937 current->id()); | 1941 current->id()); |
| 1938 SetLiveRangeAssignedRegister(current, reg); | 1942 SetLiveRangeAssignedRegister(current, reg); |
| 1939 | 1943 |
| 1940 // This register was not free. Thus we need to find and spill | 1944 // This register was not free. Thus we need to find and spill |
| 1941 // parts of active and inactive live regions that use the same register | 1945 // parts of active and inactive live regions that use the same register |
| 1942 // at the same lifetime positions as current. | 1946 // at the same lifetime positions as current. |
| 1943 SplitAndSpillIntersecting(current); | 1947 SplitAndSpillIntersecting(current); |
| 1944 } | 1948 } |
| 1945 | 1949 |
| 1946 | 1950 |
| 1951 static const InstructionBlock* GetContainingLoop( |
| 1952 const InstructionSequence* sequence, const InstructionBlock* block) { |
| 1953 BasicBlock::RpoNumber index = block->loop_header(); |
| 1954 if (!index.IsValid()) return NULL; |
| 1955 return sequence->InstructionBlockAt(index); |
| 1956 } |
| 1957 |
| 1958 |
| 1947 LifetimePosition RegisterAllocator::FindOptimalSpillingPos( | 1959 LifetimePosition RegisterAllocator::FindOptimalSpillingPos( |
| 1948 LiveRange* range, LifetimePosition pos) { | 1960 LiveRange* range, LifetimePosition pos) { |
| 1949 const InstructionBlock* block = GetInstructionBlock(pos.InstructionStart()); | 1961 const InstructionBlock* block = GetInstructionBlock(pos.InstructionStart()); |
| 1950 const InstructionBlock* loop_header = | 1962 const InstructionBlock* loop_header = |
| 1951 block->IsLoopHeader() ? block : code()->GetContainingLoop(block); | 1963 block->IsLoopHeader() ? block : GetContainingLoop(code(), block); |
| 1952 | 1964 |
| 1953 if (loop_header == NULL) return pos; | 1965 if (loop_header == NULL) return pos; |
| 1954 | 1966 |
| 1955 UsePosition* prev_use = range->PreviousUsePositionRegisterIsBeneficial(pos); | 1967 UsePosition* prev_use = range->PreviousUsePositionRegisterIsBeneficial(pos); |
| 1956 | 1968 |
| 1957 while (loop_header != NULL) { | 1969 while (loop_header != NULL) { |
| 1958 // We are going to spill live range inside the loop. | 1970 // We are going to spill live range inside the loop. |
| 1959 // If possible try to move spilling position backwards to loop header. | 1971 // If possible try to move spilling position backwards to loop header. |
| 1960 // This will reduce number of memory moves on the back edge. | 1972 // This will reduce number of memory moves on the back edge. |
| 1961 LifetimePosition loop_start = LifetimePosition::FromInstructionIndex( | 1973 LifetimePosition loop_start = LifetimePosition::FromInstructionIndex( |
| 1962 loop_header->first_instruction_index()); | 1974 loop_header->first_instruction_index()); |
| 1963 | 1975 |
| 1964 if (range->Covers(loop_start)) { | 1976 if (range->Covers(loop_start)) { |
| 1965 if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) { | 1977 if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) { |
| 1966 // No register beneficial use inside the loop before the pos. | 1978 // No register beneficial use inside the loop before the pos. |
| 1967 pos = loop_start; | 1979 pos = loop_start; |
| 1968 } | 1980 } |
| 1969 } | 1981 } |
| 1970 | 1982 |
| 1971 // Try hoisting out to an outer loop. | 1983 // Try hoisting out to an outer loop. |
| 1972 loop_header = code()->GetContainingLoop(loop_header); | 1984 loop_header = GetContainingLoop(code(), loop_header); |
| 1973 } | 1985 } |
| 1974 | 1986 |
| 1975 return pos; | 1987 return pos; |
| 1976 } | 1988 } |
| 1977 | 1989 |
| 1978 | 1990 |
| 1979 void RegisterAllocator::SplitAndSpillIntersecting(LiveRange* current) { | 1991 void RegisterAllocator::SplitAndSpillIntersecting(LiveRange* current) { |
| 1980 DCHECK(current->HasRegisterAssigned()); | 1992 DCHECK(current->HasRegisterAssigned()); |
| 1981 int reg = current->assigned_register(); | 1993 int reg = current->assigned_register(); |
| 1982 LifetimePosition split_pos = current->Start(); | 1994 LifetimePosition split_pos = current->Start(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2079 | 2091 |
| 2080 if (end_block == start_block) { | 2092 if (end_block == start_block) { |
| 2081 // The interval is split in the same basic block. Split at the latest | 2093 // The interval is split in the same basic block. Split at the latest |
| 2082 // possible position. | 2094 // possible position. |
| 2083 return end; | 2095 return end; |
| 2084 } | 2096 } |
| 2085 | 2097 |
| 2086 const InstructionBlock* block = end_block; | 2098 const InstructionBlock* block = end_block; |
| 2087 // Find header of outermost loop. | 2099 // Find header of outermost loop. |
| 2088 // TODO(titzer): fix redundancy below. | 2100 // TODO(titzer): fix redundancy below. |
| 2089 while (code()->GetContainingLoop(block) != NULL && | 2101 while (GetContainingLoop(code(), block) != NULL && |
| 2090 code()->GetContainingLoop(block)->rpo_number().ToInt() > | 2102 GetContainingLoop(code(), block)->rpo_number().ToInt() > |
| 2091 start_block->rpo_number().ToInt()) { | 2103 start_block->rpo_number().ToInt()) { |
| 2092 block = code()->GetContainingLoop(block); | 2104 block = GetContainingLoop(code(), block); |
| 2093 } | 2105 } |
| 2094 | 2106 |
| 2095 // We did not find any suitable outer loop. Split at the latest possible | 2107 // We did not find any suitable outer loop. Split at the latest possible |
| 2096 // position unless end_block is a loop header itself. | 2108 // position unless end_block is a loop header itself. |
| 2097 if (block == end_block && !end_block->IsLoopHeader()) return end; | 2109 if (block == end_block && !end_block->IsLoopHeader()) return end; |
| 2098 | 2110 |
| 2099 return LifetimePosition::FromInstructionIndex( | 2111 return LifetimePosition::FromInstructionIndex( |
| 2100 block->first_instruction_index()); | 2112 block->first_instruction_index()); |
| 2101 } | 2113 } |
| 2102 | 2114 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2146 void RegisterAllocator::Spill(LiveRange* range) { | 2158 void RegisterAllocator::Spill(LiveRange* range) { |
| 2147 DCHECK(!range->IsSpilled()); | 2159 DCHECK(!range->IsSpilled()); |
| 2148 TraceAlloc("Spilling live range %d\n", range->id()); | 2160 TraceAlloc("Spilling live range %d\n", range->id()); |
| 2149 LiveRange* first = range->TopLevel(); | 2161 LiveRange* first = range->TopLevel(); |
| 2150 | 2162 |
| 2151 if (!first->HasAllocatedSpillOperand()) { | 2163 if (!first->HasAllocatedSpillOperand()) { |
| 2152 InstructionOperand* op = TryReuseSpillSlot(range); | 2164 InstructionOperand* op = TryReuseSpillSlot(range); |
| 2153 if (op == NULL) { | 2165 if (op == NULL) { |
| 2154 // Allocate a new operand referring to the spill slot. | 2166 // Allocate a new operand referring to the spill slot. |
| 2155 RegisterKind kind = range->Kind(); | 2167 RegisterKind kind = range->Kind(); |
| 2156 int index = code()->frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS); | 2168 int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS); |
| 2157 if (kind == DOUBLE_REGISTERS) { | 2169 if (kind == DOUBLE_REGISTERS) { |
| 2158 op = DoubleStackSlotOperand::Create(index, zone()); | 2170 op = DoubleStackSlotOperand::Create(index, zone()); |
| 2159 } else { | 2171 } else { |
| 2160 DCHECK(kind == GENERAL_REGISTERS); | 2172 DCHECK(kind == GENERAL_REGISTERS); |
| 2161 op = StackSlotOperand::Create(index, zone()); | 2173 op = StackSlotOperand::Create(index, zone()); |
| 2162 } | 2174 } |
| 2163 } | 2175 } |
| 2164 first->SetSpillOperand(op); | 2176 first->SetSpillOperand(op); |
| 2165 } | 2177 } |
| 2166 range->MakeSpilled(code_zone()); | 2178 range->MakeSpilled(code_zone()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2191 } else { | 2203 } else { |
| 2192 DCHECK(range->Kind() == GENERAL_REGISTERS); | 2204 DCHECK(range->Kind() == GENERAL_REGISTERS); |
| 2193 assigned_registers_->Add(reg); | 2205 assigned_registers_->Add(reg); |
| 2194 } | 2206 } |
| 2195 range->set_assigned_register(reg, code_zone()); | 2207 range->set_assigned_register(reg, code_zone()); |
| 2196 } | 2208 } |
| 2197 | 2209 |
| 2198 | 2210 |
| 2199 RegisterAllocatorPhase::RegisterAllocatorPhase(const char* name, | 2211 RegisterAllocatorPhase::RegisterAllocatorPhase(const char* name, |
| 2200 RegisterAllocator* allocator) | 2212 RegisterAllocator* allocator) |
| 2201 : CompilationPhase(name, allocator->code()->linkage()->info()), | 2213 : CompilationPhase(name, allocator->info()), allocator_(allocator) { |
| 2202 allocator_(allocator) { | |
| 2203 if (FLAG_turbo_stats) { | 2214 if (FLAG_turbo_stats) { |
| 2204 allocator_zone_start_allocation_size_ = | 2215 allocator_zone_start_allocation_size_ = |
| 2205 allocator->zone()->allocation_size(); | 2216 allocator->zone()->allocation_size(); |
| 2206 } | 2217 } |
| 2207 } | 2218 } |
| 2208 | 2219 |
| 2209 | 2220 |
| 2210 RegisterAllocatorPhase::~RegisterAllocatorPhase() { | 2221 RegisterAllocatorPhase::~RegisterAllocatorPhase() { |
| 2211 if (FLAG_turbo_stats) { | 2222 if (FLAG_turbo_stats) { |
| 2212 unsigned size = allocator_->zone()->allocation_size() - | 2223 unsigned size = allocator_->zone()->allocation_size() - |
| 2213 allocator_zone_start_allocation_size_; | 2224 allocator_zone_start_allocation_size_; |
| 2214 isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size); | 2225 isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size); |
| 2215 } | 2226 } |
| 2216 #ifdef DEBUG | 2227 #ifdef DEBUG |
| 2217 if (allocator_ != NULL) allocator_->Verify(); | 2228 if (allocator_ != NULL) allocator_->Verify(); |
| 2218 #endif | 2229 #endif |
| 2219 } | 2230 } |
| 2220 } | 2231 } |
| 2221 } | 2232 } |
| 2222 } // namespace v8::internal::compiler | 2233 } // namespace v8::internal::compiler |
| OLD | NEW |