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...) 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...) 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...) 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...) 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...) 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...) 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...) 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...) 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 |