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

Side by Side Diff: src/compiler/scheduler.cc

Issue 928213003: Model exceptional edges from call nodes in TurboFan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased. Created 5 years, 10 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
« no previous file with comments | « src/compiler/schedule.cc ('k') | src/compiler/verifier.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/scheduler.h" 5 #include "src/compiler/scheduler.h"
6 6
7 #include "src/bit-vector.h" 7 #include "src/bit-vector.h"
8 #include "src/compiler/common-operator.h" 8 #include "src/compiler/common-operator.h"
9 #include "src/compiler/control-equivalence.h" 9 #include "src/compiler/control-equivalence.h"
10 #include "src/compiler/graph.h" 10 #include "src/compiler/graph.h"
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 279 }
280 } 280 }
281 DCHECK(component_entry_); 281 DCHECK(component_entry_);
282 282
283 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { 283 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) {
284 ConnectBlocks(*i); // Connect block to its predecessor/successors. 284 ConnectBlocks(*i); // Connect block to its predecessor/successors.
285 } 285 }
286 } 286 }
287 287
288 private: 288 private:
289 // TODO(mstarzinger): Only for Scheduler::FuseFloatingControl. 289 friend class ScheduleLateNodeVisitor;
290 friend class Scheduler; 290 friend class Scheduler;
291 291
292 void FixNode(BasicBlock* block, Node* node) { 292 void FixNode(BasicBlock* block, Node* node) {
293 schedule_->AddNode(block, node); 293 schedule_->AddNode(block, node);
294 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 294 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
295 } 295 }
296 296
297 void Queue(Node* node) { 297 void Queue(Node* node) {
298 // Mark the connected control nodes as they are queued. 298 // Mark the connected control nodes as they are queued.
299 if (!queued_.Get(node)) { 299 if (!queued_.Get(node)) {
(...skipping 13 matching lines...) Expand all
313 FixNode(schedule_->start(), node); 313 FixNode(schedule_->start(), node);
314 break; 314 break;
315 case IrOpcode::kLoop: 315 case IrOpcode::kLoop:
316 case IrOpcode::kMerge: 316 case IrOpcode::kMerge:
317 BuildBlockForNode(node); 317 BuildBlockForNode(node);
318 break; 318 break;
319 case IrOpcode::kBranch: 319 case IrOpcode::kBranch:
320 case IrOpcode::kSwitch: 320 case IrOpcode::kSwitch:
321 BuildBlocksForSuccessors(node); 321 BuildBlocksForSuccessors(node);
322 break; 322 break;
323 case IrOpcode::kCall:
324 if (IsExceptionalCall(node)) {
325 BuildBlocksForSuccessors(node);
326 }
327 break;
323 default: 328 default:
324 break; 329 break;
325 } 330 }
326 } 331 }
327 332
328 void ConnectBlocks(Node* node) { 333 void ConnectBlocks(Node* node) {
329 switch (node->opcode()) { 334 switch (node->opcode()) {
330 case IrOpcode::kLoop: 335 case IrOpcode::kLoop:
331 case IrOpcode::kMerge: 336 case IrOpcode::kMerge:
332 ConnectMerge(node); 337 ConnectMerge(node);
333 break; 338 break;
334 case IrOpcode::kBranch: 339 case IrOpcode::kBranch:
335 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 340 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
336 ConnectBranch(node); 341 ConnectBranch(node);
337 break; 342 break;
338 case IrOpcode::kSwitch: 343 case IrOpcode::kSwitch:
339 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 344 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
340 ConnectSwitch(node); 345 ConnectSwitch(node);
341 break; 346 break;
342 case IrOpcode::kReturn: 347 case IrOpcode::kReturn:
343 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 348 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
344 ConnectReturn(node); 349 ConnectReturn(node);
345 break; 350 break;
346 case IrOpcode::kThrow: 351 case IrOpcode::kThrow:
347 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 352 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
348 ConnectThrow(node); 353 ConnectThrow(node);
349 break; 354 break;
355 case IrOpcode::kCall:
356 if (IsExceptionalCall(node)) {
357 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
358 ConnectCall(node);
359 }
360 break;
350 default: 361 default:
351 break; 362 break;
352 } 363 }
353 } 364 }
354 365
355 BasicBlock* BuildBlockForNode(Node* node) { 366 BasicBlock* BuildBlockForNode(Node* node) {
356 BasicBlock* block = schedule_->block(node); 367 BasicBlock* block = schedule_->block(node);
357 if (block == NULL) { 368 if (block == NULL) {
358 block = schedule_->NewBasicBlock(); 369 block = schedule_->NewBasicBlock();
359 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(), 370 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(),
(...skipping 14 matching lines...) Expand all
374 385
375 void CollectSuccessorBlocks(Node* node, BasicBlock** successor_blocks, 386 void CollectSuccessorBlocks(Node* node, BasicBlock** successor_blocks,
376 size_t successor_cnt) { 387 size_t successor_cnt) {
377 Node** successors = reinterpret_cast<Node**>(successor_blocks); 388 Node** successors = reinterpret_cast<Node**>(successor_blocks);
378 NodeProperties::CollectControlProjections(node, successors, successor_cnt); 389 NodeProperties::CollectControlProjections(node, successors, successor_cnt);
379 for (size_t index = 0; index < successor_cnt; ++index) { 390 for (size_t index = 0; index < successor_cnt; ++index) {
380 successor_blocks[index] = schedule_->block(successors[index]); 391 successor_blocks[index] = schedule_->block(successors[index]);
381 } 392 }
382 } 393 }
383 394
395 BasicBlock* FindPredecessorBlock(Node* node) {
396 BasicBlock* predecessor_block = nullptr;
397 while (true) {
398 predecessor_block = schedule_->block(node);
399 if (predecessor_block != nullptr) break;
400 node = NodeProperties::GetControlInput(node);
401 }
402 return predecessor_block;
403 }
404
405 void ConnectCall(Node* call) {
406 BasicBlock* successor_blocks[2];
407 CollectSuccessorBlocks(call, successor_blocks, arraysize(successor_blocks));
408
409 // Consider the exception continuation to be deferred.
410 successor_blocks[1]->set_deferred(true);
411
412 Node* call_control = NodeProperties::GetControlInput(call);
413 BasicBlock* call_block = FindPredecessorBlock(call_control);
414 TraceConnect(call, call_block, successor_blocks[0]);
415 TraceConnect(call, call_block, successor_blocks[1]);
416 schedule_->AddCall(call_block, call, successor_blocks[0],
417 successor_blocks[1]);
418 }
419
384 void ConnectBranch(Node* branch) { 420 void ConnectBranch(Node* branch) {
385 BasicBlock* successor_blocks[2]; 421 BasicBlock* successor_blocks[2];
386 CollectSuccessorBlocks(branch, successor_blocks, 422 CollectSuccessorBlocks(branch, successor_blocks,
387 arraysize(successor_blocks)); 423 arraysize(successor_blocks));
388 424
389 // Consider branch hints. 425 // Consider branch hints.
390 switch (BranchHintOf(branch->op())) { 426 switch (BranchHintOf(branch->op())) {
391 case BranchHint::kNone: 427 case BranchHint::kNone:
392 break; 428 break;
393 case BranchHint::kTrue: 429 case BranchHint::kTrue:
394 successor_blocks[1]->set_deferred(true); 430 successor_blocks[1]->set_deferred(true);
395 break; 431 break;
396 case BranchHint::kFalse: 432 case BranchHint::kFalse:
397 successor_blocks[0]->set_deferred(true); 433 successor_blocks[0]->set_deferred(true);
398 break; 434 break;
399 } 435 }
400 436
401 if (branch == component_entry_) { 437 if (branch == component_entry_) {
402 TraceConnect(branch, component_start_, successor_blocks[0]); 438 TraceConnect(branch, component_start_, successor_blocks[0]);
403 TraceConnect(branch, component_start_, successor_blocks[1]); 439 TraceConnect(branch, component_start_, successor_blocks[1]);
404 schedule_->InsertBranch(component_start_, component_end_, branch, 440 schedule_->InsertBranch(component_start_, component_end_, branch,
405 successor_blocks[0], successor_blocks[1]); 441 successor_blocks[0], successor_blocks[1]);
406 } else { 442 } else {
407 Node* branch_block_node = NodeProperties::GetControlInput(branch); 443 Node* branch_control = NodeProperties::GetControlInput(branch);
408 BasicBlock* branch_block = schedule_->block(branch_block_node); 444 BasicBlock* branch_block = FindPredecessorBlock(branch_control);
409 DCHECK_NOT_NULL(branch_block);
410
411 TraceConnect(branch, branch_block, successor_blocks[0]); 445 TraceConnect(branch, branch_block, successor_blocks[0]);
412 TraceConnect(branch, branch_block, successor_blocks[1]); 446 TraceConnect(branch, branch_block, successor_blocks[1]);
413 schedule_->AddBranch(branch_block, branch, successor_blocks[0], 447 schedule_->AddBranch(branch_block, branch, successor_blocks[0],
414 successor_blocks[1]); 448 successor_blocks[1]);
415 } 449 }
416 } 450 }
417 451
418 void ConnectSwitch(Node* sw) { 452 void ConnectSwitch(Node* sw) {
419 size_t const successor_count = sw->op()->ControlOutputCount(); 453 size_t const successor_count = sw->op()->ControlOutputCount();
420 BasicBlock** successor_blocks = 454 BasicBlock** successor_blocks =
421 zone_->NewArray<BasicBlock*>(successor_count); 455 zone_->NewArray<BasicBlock*>(successor_count);
422 CollectSuccessorBlocks(sw, successor_blocks, successor_count); 456 CollectSuccessorBlocks(sw, successor_blocks, successor_count);
423 457
424 if (sw == component_entry_) { 458 if (sw == component_entry_) {
425 for (size_t index = 0; index < successor_count; ++index) { 459 for (size_t index = 0; index < successor_count; ++index) {
426 TraceConnect(sw, component_start_, successor_blocks[index]); 460 TraceConnect(sw, component_start_, successor_blocks[index]);
427 } 461 }
428 schedule_->InsertSwitch(component_start_, component_end_, sw, 462 schedule_->InsertSwitch(component_start_, component_end_, sw,
429 successor_blocks, successor_count); 463 successor_blocks, successor_count);
430 } else { 464 } else {
431 Node* sw_block_node = NodeProperties::GetControlInput(sw); 465 Node* switch_control = NodeProperties::GetControlInput(sw);
432 BasicBlock* sw_block = schedule_->block(sw_block_node); 466 BasicBlock* switch_block = FindPredecessorBlock(switch_control);
433 DCHECK_NOT_NULL(sw_block);
434
435 for (size_t index = 0; index < successor_count; ++index) { 467 for (size_t index = 0; index < successor_count; ++index) {
436 TraceConnect(sw, sw_block, successor_blocks[index]); 468 TraceConnect(sw, switch_block, successor_blocks[index]);
437 } 469 }
438 schedule_->AddSwitch(sw_block, sw, successor_blocks, successor_count); 470 schedule_->AddSwitch(switch_block, sw, successor_blocks, successor_count);
439 } 471 }
440 } 472 }
441 473
442 void ConnectMerge(Node* merge) { 474 void ConnectMerge(Node* merge) {
443 // Don't connect the special merge at the end to its predecessors. 475 // Don't connect the special merge at the end to its predecessors.
444 if (IsFinalMerge(merge)) return; 476 if (IsFinalMerge(merge)) return;
445 477
446 BasicBlock* block = schedule_->block(merge); 478 BasicBlock* block = schedule_->block(merge);
447 DCHECK_NOT_NULL(block); 479 DCHECK_NOT_NULL(block);
448 // For all of the merge's control inputs, add a goto at the end to the 480 // For all of the merge's control inputs, add a goto at the end to the
449 // merge's basic block. 481 // merge's basic block.
450 for (Node* const input : merge->inputs()) { 482 for (Node* const input : merge->inputs()) {
451 BasicBlock* predecessor_block = schedule_->block(input); 483 BasicBlock* predecessor_block = FindPredecessorBlock(input);
452 TraceConnect(merge, predecessor_block, block); 484 TraceConnect(merge, predecessor_block, block);
453 schedule_->AddGoto(predecessor_block, block); 485 schedule_->AddGoto(predecessor_block, block);
454 } 486 }
455 } 487 }
456 488
457 void ConnectReturn(Node* ret) { 489 void ConnectReturn(Node* ret) {
458 Node* return_block_node = NodeProperties::GetControlInput(ret); 490 Node* return_control = NodeProperties::GetControlInput(ret);
459 BasicBlock* return_block = schedule_->block(return_block_node); 491 BasicBlock* return_block = FindPredecessorBlock(return_control);
460 TraceConnect(ret, return_block, NULL); 492 TraceConnect(ret, return_block, NULL);
461 schedule_->AddReturn(return_block, ret); 493 schedule_->AddReturn(return_block, ret);
462 } 494 }
463 495
464 void ConnectThrow(Node* thr) { 496 void ConnectThrow(Node* thr) {
465 Node* throw_block_node = NodeProperties::GetControlInput(thr); 497 Node* throw_control = NodeProperties::GetControlInput(thr);
466 BasicBlock* throw_block = schedule_->block(throw_block_node); 498 BasicBlock* throw_block = FindPredecessorBlock(throw_control);
467 TraceConnect(thr, throw_block, NULL); 499 TraceConnect(thr, throw_block, NULL);
468 schedule_->AddThrow(throw_block, thr); 500 schedule_->AddThrow(throw_block, thr);
469 } 501 }
470 502
471 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) { 503 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) {
472 DCHECK_NOT_NULL(block); 504 DCHECK_NOT_NULL(block);
473 if (succ == NULL) { 505 if (succ == NULL) {
474 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(), 506 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(),
475 block->id().ToInt()); 507 block->id().ToInt());
476 } else { 508 } else {
477 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(), 509 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(),
478 block->id().ToInt(), succ->id().ToInt()); 510 block->id().ToInt(), succ->id().ToInt());
479 } 511 }
480 } 512 }
481 513
514 bool IsExceptionalCall(Node* node) {
515 for (Node* const use : node->uses()) {
516 if (use->opcode() == IrOpcode::kIfException) return true;
517 }
518 return false;
519 }
520
482 bool IsFinalMerge(Node* node) { 521 bool IsFinalMerge(Node* node) {
483 return (node->opcode() == IrOpcode::kMerge && 522 return (node->opcode() == IrOpcode::kMerge &&
484 node == scheduler_->graph_->end()->InputAt(0)); 523 node == scheduler_->graph_->end()->InputAt(0));
485 } 524 }
486 525
487 bool IsSingleEntrySingleExitRegion(Node* entry, Node* exit) const { 526 bool IsSingleEntrySingleExitRegion(Node* entry, Node* exit) const {
488 size_t entry_class = scheduler_->equivalence_->ClassOf(entry); 527 size_t entry_class = scheduler_->equivalence_->ClassOf(entry);
489 size_t exit_class = scheduler_->equivalence_->ClassOf(exit); 528 size_t exit_class = scheduler_->equivalence_->ClassOf(exit);
490 return entry != exit && entry_class == exit_class; 529 return entry != exit && entry_class == exit_class;
491 } 530 }
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 block = hoist_block; 1356 block = hoist_block;
1318 hoist_block = GetPreHeader(hoist_block); 1357 hoist_block = GetPreHeader(hoist_block);
1319 } while (hoist_block && 1358 } while (hoist_block &&
1320 hoist_block->dominator_depth() >= min_block->dominator_depth()); 1359 hoist_block->dominator_depth() >= min_block->dominator_depth());
1321 } else if (scheduler_->flags_ & Scheduler::kSplitNodes) { 1360 } else if (scheduler_->flags_ & Scheduler::kSplitNodes) {
1322 // Split the {node} if beneficial and return the new {block} for it. 1361 // Split the {node} if beneficial and return the new {block} for it.
1323 block = SplitNode(block, node); 1362 block = SplitNode(block, node);
1324 } 1363 }
1325 1364
1326 // Schedule the node or a floating control structure. 1365 // Schedule the node or a floating control structure.
1327 if (NodeProperties::IsControl(node)) { 1366 if (IrOpcode::IsMergeOpcode(node->opcode())) {
1328 ScheduleFloatingControl(block, node); 1367 ScheduleFloatingControl(block, node);
1329 } else { 1368 } else {
1330 ScheduleNode(block, node); 1369 ScheduleNode(block, node);
1331 } 1370 }
1332 } 1371 }
1333 1372
1334 // Mark {block} and push its non-marked predecessor on the marking queue. 1373 // Mark {block} and push its non-marked predecessor on the marking queue.
1335 void MarkBlock(BasicBlock* block) { 1374 void MarkBlock(BasicBlock* block) {
1336 DCHECK_LT(block->id().ToSize(), marked_.size()); 1375 DCHECK_LT(block->id().ToSize(), marked_.size());
1337 marked_[block->id().ToSize()] = true; 1376 marked_[block->id().ToSize()] = true;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 for (Edge edge : node->use_edges()) { 1480 for (Edge edge : node->use_edges()) {
1442 BasicBlock* use_block = GetBlockForUse(edge); 1481 BasicBlock* use_block = GetBlockForUse(edge);
1443 block = block == NULL ? use_block : use_block == NULL 1482 block = block == NULL ? use_block : use_block == NULL
1444 ? block 1483 ? block
1445 : BasicBlock::GetCommonDominator( 1484 : BasicBlock::GetCommonDominator(
1446 block, use_block); 1485 block, use_block);
1447 } 1486 }
1448 return block; 1487 return block;
1449 } 1488 }
1450 1489
1490 BasicBlock* FindPredecessorBlock(Node* node) {
1491 return scheduler_->control_flow_builder_->FindPredecessorBlock(node);
1492 }
1493
1451 BasicBlock* GetBlockForUse(Edge edge) { 1494 BasicBlock* GetBlockForUse(Edge edge) {
1452 Node* use = edge.from(); 1495 Node* use = edge.from();
1453 IrOpcode::Value opcode = use->opcode(); 1496 if (IrOpcode::IsPhiOpcode(use->opcode())) {
1454 if (IrOpcode::IsPhiOpcode(opcode)) {
1455 // If the use is from a coupled (i.e. floating) phi, compute the common 1497 // If the use is from a coupled (i.e. floating) phi, compute the common
1456 // dominator of its uses. This will not recurse more than one level. 1498 // dominator of its uses. This will not recurse more than one level.
1457 if (scheduler_->GetPlacement(use) == Scheduler::kCoupled) { 1499 if (scheduler_->GetPlacement(use) == Scheduler::kCoupled) {
1458 Trace(" inspecting uses of coupled #%d:%s\n", use->id(), 1500 Trace(" inspecting uses of coupled #%d:%s\n", use->id(),
1459 use->op()->mnemonic()); 1501 use->op()->mnemonic());
1460 DCHECK_EQ(edge.to(), NodeProperties::GetControlInput(use)); 1502 DCHECK_EQ(edge.to(), NodeProperties::GetControlInput(use));
1461 return GetCommonDominatorOfUses(use); 1503 return GetCommonDominatorOfUses(use);
1462 } 1504 }
1463 // If the use is from a fixed (i.e. non-floating) phi, use the block 1505 // If the use is from a fixed (i.e. non-floating) phi, we use the
1464 // of the corresponding control input to the merge. 1506 // predecessor block of the corresponding control input to the merge.
1465 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) { 1507 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
1466 Trace(" input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(), 1508 Trace(" input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(),
1467 use->op()->mnemonic()); 1509 use->op()->mnemonic());
1468 Node* merge = NodeProperties::GetControlInput(use, 0); 1510 Node* merge = NodeProperties::GetControlInput(use, 0);
1469 opcode = merge->opcode(); 1511 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
1470 DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop); 1512 Node* input = NodeProperties::GetControlInput(merge, edge.index());
1471 use = NodeProperties::GetControlInput(merge, edge.index()); 1513 return FindPredecessorBlock(input);
1514 }
1515 } else if (IrOpcode::IsMergeOpcode(use->opcode())) {
1516 // If the use is from a fixed (i.e. non-floating) merge, we use the
1517 // predecessor block of the current input to the merge.
1518 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
1519 Trace(" input@%d into a fixed merge #%d:%s\n", edge.index(), use->id(),
1520 use->op()->mnemonic());
1521 return FindPredecessorBlock(edge.to());
1472 } 1522 }
1473 } 1523 }
1474 BasicBlock* result = schedule_->block(use); 1524 BasicBlock* result = schedule_->block(use);
1475 if (result == NULL) return NULL; 1525 if (result == NULL) return NULL;
1476 Trace(" must dominate use #%d:%s in B%d\n", use->id(), 1526 Trace(" must dominate use #%d:%s in B%d\n", use->id(),
1477 use->op()->mnemonic(), result->id().ToInt()); 1527 use->op()->mnemonic(), result->id().ToInt());
1478 return result; 1528 return result;
1479 } 1529 }
1480 1530
1481 void ScheduleFloatingControl(BasicBlock* block, Node* node) { 1531 void ScheduleFloatingControl(BasicBlock* block, Node* node) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 for (Node* const node : *nodes) { 1660 for (Node* const node : *nodes) {
1611 schedule_->SetBlockForNode(to, node); 1661 schedule_->SetBlockForNode(to, node);
1612 scheduled_nodes_[to->id().ToSize()].push_back(node); 1662 scheduled_nodes_[to->id().ToSize()].push_back(node);
1613 } 1663 }
1614 nodes->clear(); 1664 nodes->clear();
1615 } 1665 }
1616 1666
1617 } // namespace compiler 1667 } // namespace compiler
1618 } // namespace internal 1668 } // namespace internal
1619 } // namespace v8 1669 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/schedule.cc ('k') | src/compiler/verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698