Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 bool is_eval) | 76 bool is_eval) |
| 77 : is_eval_(is_eval), | 77 : is_eval_(is_eval), |
| 78 script_(script), | 78 script_(script), |
| 79 deferred_(8), | 79 deferred_(8), |
| 80 masm_(new MacroAssembler(NULL, buffer_size)), | 80 masm_(new MacroAssembler(NULL, buffer_size)), |
| 81 scope_(NULL), | 81 scope_(NULL), |
| 82 frame_(NULL), | 82 frame_(NULL), |
| 83 allocator_(NULL), | 83 allocator_(NULL), |
| 84 cc_reg_(no_condition), | 84 cc_reg_(no_condition), |
| 85 state_(NULL), | 85 state_(NULL), |
| 86 is_inside_try_(false), | |
| 87 break_stack_height_(0), | 86 break_stack_height_(0), |
| 88 loop_nesting_(0), | 87 loop_nesting_(0), |
| 89 function_return_is_shadowed_(false), | 88 function_return_is_shadowed_(false), |
| 90 in_spilled_code_(false) { | 89 in_spilled_code_(false) { |
| 91 } | 90 } |
| 92 | 91 |
| 93 | 92 |
| 94 void CodeGenerator::SetFrame(VirtualFrame* new_frame) { | 93 void CodeGenerator::SetFrame(VirtualFrame* new_frame) { |
| 95 if (has_valid_frame()) { | 94 if (has_valid_frame()) { |
| 96 frame_->DetachFromCodeGenerator(); | 95 frame_->DetachFromCodeGenerator(); |
| (...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1620 ASSERT(!in_spilled_code()); | 1619 ASSERT(!in_spilled_code()); |
| 1621 Comment cmnt(masm_, "[ BreakStatement"); | 1620 Comment cmnt(masm_, "[ BreakStatement"); |
| 1622 CodeForStatement(node); | 1621 CodeForStatement(node); |
| 1623 CleanStack(break_stack_height_ - node->target()->break_stack_height()); | 1622 CleanStack(break_stack_height_ - node->target()->break_stack_height()); |
| 1624 node->target()->break_target()->Jump(); | 1623 node->target()->break_target()->Jump(); |
| 1625 } | 1624 } |
| 1626 | 1625 |
| 1627 | 1626 |
| 1628 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { | 1627 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { |
| 1629 ASSERT(!in_spilled_code()); | 1628 ASSERT(!in_spilled_code()); |
| 1630 VirtualFrame::SpilledScope spilled_scope(this); | |
| 1631 Comment cmnt(masm_, "[ ReturnStatement"); | 1629 Comment cmnt(masm_, "[ ReturnStatement"); |
| 1632 CodeForStatement(node); | |
| 1633 LoadAndSpill(node->expression()); | |
| 1634 | 1630 |
| 1635 // Move the function result into eax | 1631 if (function_return_is_shadowed_) { |
| 1636 frame_->EmitPop(eax); | 1632 // If the function return is shadowed, we spill all information |
| 1637 | 1633 // and just jump to the label. |
| 1638 // If we're inside a try statement or the return instruction | 1634 VirtualFrame::SpilledScope spilled_scope(this); |
| 1639 // sequence has been generated, we just jump to that | 1635 CodeForStatement(node); |
| 1640 // point. Otherwise, we generate the return instruction sequence and | 1636 LoadAndSpill(node->expression()); |
| 1641 // bind the function return label. | 1637 frame_->EmitPop(eax); |
| 1642 if (is_inside_try_ || function_return_.is_bound()) { | |
| 1643 function_return_.Jump(); | 1638 function_return_.Jump(); |
| 1644 } else { | 1639 } else { |
| 1645 function_return_.Bind(); | 1640 // Load the returned value. |
| 1646 if (FLAG_trace) { | 1641 CodeForStatement(node); |
| 1647 frame_->EmitPush(eax); // undo the pop(eax) from above | 1642 Load(node->expression()); |
| 1648 frame_->CallRuntime(Runtime::kTraceExit, 1); | 1643 |
| 1644 // Pop the result from the frame and prepare the frame for | |
| 1645 // returning thus making it easier to merge. | |
| 1646 Result result = frame_->Pop(); | |
| 1647 frame_->PrepareForReturn(); | |
| 1648 | |
| 1649 // Move the result into register eax where it belongs. | |
| 1650 result.ToRegister(eax); | |
| 1651 result.Unuse(); | |
|
Kevin Millikin (Chromium)
2009/01/07 10:25:12
Since the reference to eax is live in the next bas
| |
| 1652 | |
| 1653 // If the function return label is already bound, we reuse the | |
| 1654 // code by jumping to the return site. | |
| 1655 if (function_return_.is_bound()) { | |
| 1656 function_return_.Jump(); | |
| 1657 } else { | |
| 1658 function_return_.Bind(); | |
| 1659 if (FLAG_trace) { | |
| 1660 frame_->EmitPush(eax); // Materialize result on the stack. | |
|
Kevin Millikin (Chromium)
2009/01/07 10:25:12
EmitPush assumes the frame is spilled. This shoul
| |
| 1661 frame_->CallRuntime(Runtime::kTraceExit, 1); | |
| 1662 } | |
| 1663 | |
| 1664 // Add a label for checking the size of the code used for returning. | |
| 1665 Label check_exit_codesize; | |
| 1666 __ bind(&check_exit_codesize); | |
| 1667 | |
| 1668 // Leave the frame and return popping the arguments and the | |
| 1669 // receiver. | |
| 1670 frame_->Exit(); | |
| 1671 __ ret((scope_->num_parameters() + 1) * kPointerSize); | |
| 1672 DeleteFrame(); | |
| 1673 | |
| 1674 // Check that the size of the code used for returning matches what is | |
| 1675 // expected by the debugger. | |
| 1676 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength, | |
| 1677 __ SizeOfCodeGeneratedSince(&check_exit_codesize)); | |
| 1649 } | 1678 } |
| 1650 | |
| 1651 // Add a label for checking the size of the code used for returning. | |
| 1652 Label check_exit_codesize; | |
| 1653 __ bind(&check_exit_codesize); | |
| 1654 | |
| 1655 // Leave the frame and return popping the arguments and the | |
| 1656 // receiver. | |
| 1657 frame_->Exit(); | |
| 1658 __ ret((scope_->num_parameters() + 1) * kPointerSize); | |
| 1659 DeleteFrame(); | |
| 1660 | |
| 1661 // Check that the size of the code used for returning matches what is | |
| 1662 // expected by the debugger. | |
| 1663 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength, | |
| 1664 __ SizeOfCodeGeneratedSince(&check_exit_codesize)); | |
| 1665 } | 1679 } |
| 1666 } | 1680 } |
| 1667 | 1681 |
| 1668 | 1682 |
| 1669 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { | 1683 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { |
| 1670 ASSERT(!in_spilled_code()); | 1684 ASSERT(!in_spilled_code()); |
| 1671 Comment cmnt(masm_, "[ WithEnterStatement"); | 1685 Comment cmnt(masm_, "[ WithEnterStatement"); |
| 1672 CodeForStatement(node); | 1686 CodeForStatement(node); |
| 1673 Load(node->expression()); | 1687 Load(node->expression()); |
| 1674 Result context(this); | 1688 Result context(this); |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2303 | 2317 |
| 2304 // Shadow the jump targets for all escapes from the try block, including | 2318 // Shadow the jump targets for all escapes from the try block, including |
| 2305 // returns. During shadowing, the original target is hidden as the | 2319 // returns. During shadowing, the original target is hidden as the |
| 2306 // ShadowTarget and operations on the original actually affect the | 2320 // ShadowTarget and operations on the original actually affect the |
| 2307 // shadowing target. | 2321 // shadowing target. |
| 2308 // | 2322 // |
| 2309 // We should probably try to unify the escaping targets and the return | 2323 // We should probably try to unify the escaping targets and the return |
| 2310 // target. | 2324 // target. |
| 2311 int nof_escapes = node->escaping_targets()->length(); | 2325 int nof_escapes = node->escaping_targets()->length(); |
| 2312 List<ShadowTarget*> shadows(1 + nof_escapes); | 2326 List<ShadowTarget*> shadows(1 + nof_escapes); |
| 2327 | |
| 2328 // Add the shadow target for the function return. | |
| 2329 static const int kReturnShadowIndex = 0; | |
| 2313 shadows.Add(new ShadowTarget(&function_return_)); | 2330 shadows.Add(new ShadowTarget(&function_return_)); |
| 2331 bool function_return_was_shadowed = function_return_is_shadowed_; | |
| 2332 function_return_is_shadowed_ = true; | |
| 2333 ASSERT(shadows[kReturnShadowIndex]->original_target() == &function_return_); | |
| 2334 | |
| 2335 // Add the remaining shadow targets. | |
| 2314 for (int i = 0; i < nof_escapes; i++) { | 2336 for (int i = 0; i < nof_escapes; i++) { |
| 2315 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 2337 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); |
| 2316 } | 2338 } |
| 2317 bool function_return_was_shadowed = function_return_is_shadowed_; | |
| 2318 function_return_is_shadowed_ = true; | |
| 2319 | 2339 |
| 2320 // Generate code for the statements in the try block. | 2340 // Generate code for the statements in the try block. |
| 2321 { TempAssign<bool> temp(&is_inside_try_, true); | 2341 VisitStatementsAndSpill(node->try_block()->statements()); |
| 2322 VisitStatementsAndSpill(node->try_block()->statements()); | |
| 2323 } | |
| 2324 | 2342 |
| 2325 // Stop the introduced shadowing and count the number of required unlinks. | 2343 // Stop the introduced shadowing and count the number of required unlinks. |
| 2326 // After shadowing stops, the original targets are unshadowed and the | 2344 // After shadowing stops, the original targets are unshadowed and the |
| 2327 // ShadowTargets represent the formerly shadowing targets. | 2345 // ShadowTargets represent the formerly shadowing targets. |
| 2328 int nof_unlinks = 0; | 2346 int nof_unlinks = 0; |
| 2329 for (int i = 0; i <= nof_escapes; i++) { | 2347 for (int i = 0; i <= nof_escapes; i++) { |
| 2330 shadows[i]->StopShadowing(); | 2348 shadows[i]->StopShadowing(); |
| 2331 if (shadows[i]->is_linked()) nof_unlinks++; | 2349 if (shadows[i]->is_linked()) nof_unlinks++; |
| 2332 } | 2350 } |
| 2333 function_return_is_shadowed_ = function_return_was_shadowed; | 2351 function_return_is_shadowed_ = function_return_was_shadowed; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2370 // break from (eg, for...in) may have left stuff on the stack. | 2388 // break from (eg, for...in) may have left stuff on the stack. |
| 2371 __ mov(edx, Operand::StaticVariable(handler_address)); | 2389 __ mov(edx, Operand::StaticVariable(handler_address)); |
| 2372 const int kNextOffset = StackHandlerConstants::kNextOffset + | 2390 const int kNextOffset = StackHandlerConstants::kNextOffset + |
| 2373 StackHandlerConstants::kAddressDisplacement; | 2391 StackHandlerConstants::kAddressDisplacement; |
| 2374 __ lea(esp, Operand(edx, kNextOffset)); | 2392 __ lea(esp, Operand(edx, kNextOffset)); |
| 2375 frame_->Forget(frame_->height() - handler_height); | 2393 frame_->Forget(frame_->height() - handler_height); |
| 2376 | 2394 |
| 2377 frame_->EmitPop(Operand::StaticVariable(handler_address)); | 2395 frame_->EmitPop(Operand::StaticVariable(handler_address)); |
| 2378 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 2396 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); |
| 2379 // next_sp popped. | 2397 // next_sp popped. |
| 2398 | |
| 2399 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { | |
| 2400 frame_->PrepareForReturn(); | |
| 2401 } | |
| 2380 shadows[i]->original_target()->Jump(); | 2402 shadows[i]->original_target()->Jump(); |
| 2381 } | 2403 } |
| 2382 } | 2404 } |
| 2383 | 2405 |
| 2384 exit.Bind(); | 2406 exit.Bind(); |
| 2385 } | 2407 } |
| 2386 | 2408 |
| 2387 | 2409 |
| 2388 void CodeGenerator::VisitTryFinally(TryFinally* node) { | 2410 void CodeGenerator::VisitTryFinally(TryFinally* node) { |
| 2389 ASSERT(!in_spilled_code()); | 2411 ASSERT(!in_spilled_code()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2416 | 2438 |
| 2417 // Shadow the jump targets for all escapes from the try block, including | 2439 // Shadow the jump targets for all escapes from the try block, including |
| 2418 // returns. During shadowing, the original target is hidden as the | 2440 // returns. During shadowing, the original target is hidden as the |
| 2419 // ShadowTarget and operations on the original actually affect the | 2441 // ShadowTarget and operations on the original actually affect the |
| 2420 // shadowing target. | 2442 // shadowing target. |
| 2421 // | 2443 // |
| 2422 // We should probably try to unify the escaping targets and the return | 2444 // We should probably try to unify the escaping targets and the return |
| 2423 // target. | 2445 // target. |
| 2424 int nof_escapes = node->escaping_targets()->length(); | 2446 int nof_escapes = node->escaping_targets()->length(); |
| 2425 List<ShadowTarget*> shadows(1 + nof_escapes); | 2447 List<ShadowTarget*> shadows(1 + nof_escapes); |
| 2448 | |
| 2449 // Add the shadow target for the function return. | |
| 2450 static const int kReturnShadowIndex = 0; | |
| 2426 shadows.Add(new ShadowTarget(&function_return_)); | 2451 shadows.Add(new ShadowTarget(&function_return_)); |
| 2452 bool function_return_was_shadowed = function_return_is_shadowed_; | |
| 2453 function_return_is_shadowed_ = true; | |
| 2454 ASSERT(shadows[kReturnShadowIndex]->original_target() == &function_return_); | |
| 2455 | |
| 2456 // Add the remaining shadow targets. | |
| 2427 for (int i = 0; i < nof_escapes; i++) { | 2457 for (int i = 0; i < nof_escapes; i++) { |
| 2428 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 2458 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); |
| 2429 } | 2459 } |
| 2430 bool function_return_was_shadowed = function_return_is_shadowed_; | |
| 2431 function_return_is_shadowed_ = true; | |
| 2432 | 2460 |
| 2433 // Generate code for the statements in the try block. | 2461 // Generate code for the statements in the try block. |
| 2434 { TempAssign<bool> temp(&is_inside_try_, true); | 2462 VisitStatementsAndSpill(node->try_block()->statements()); |
| 2435 VisitStatementsAndSpill(node->try_block()->statements()); | |
| 2436 } | |
| 2437 | 2463 |
| 2438 // Stop the introduced shadowing and count the number of required unlinks. | 2464 // Stop the introduced shadowing and count the number of required unlinks. |
| 2439 // After shadowing stops, the original targets are unshadowed and the | 2465 // After shadowing stops, the original targets are unshadowed and the |
| 2440 // ShadowTargets represent the formerly shadowing targets. | 2466 // ShadowTargets represent the formerly shadowing targets. |
| 2441 int nof_unlinks = 0; | 2467 int nof_unlinks = 0; |
| 2442 for (int i = 0; i <= nof_escapes; i++) { | 2468 for (int i = 0; i <= nof_escapes; i++) { |
| 2443 shadows[i]->StopShadowing(); | 2469 shadows[i]->StopShadowing(); |
| 2444 if (shadows[i]->is_linked()) nof_unlinks++; | 2470 if (shadows[i]->is_linked()) nof_unlinks++; |
| 2445 } | 2471 } |
| 2446 function_return_is_shadowed_ = function_return_was_shadowed; | 2472 function_return_is_shadowed_ = function_return_was_shadowed; |
| 2447 | 2473 |
| 2448 // If we can fall off the end of the try block, set the state on the stack | 2474 // If we can fall off the end of the try block, set the state on the stack |
| 2449 // to FALLING. | 2475 // to FALLING. |
| 2450 if (has_valid_frame()) { | 2476 if (has_valid_frame()) { |
| 2451 frame_->EmitPush(Immediate(Factory::undefined_value())); // fake TOS | 2477 frame_->EmitPush(Immediate(Factory::undefined_value())); // fake TOS |
| 2452 __ Set(ecx, Immediate(Smi::FromInt(FALLING))); | 2478 __ Set(ecx, Immediate(Smi::FromInt(FALLING))); |
| 2453 if (nof_unlinks > 0) { | 2479 if (nof_unlinks > 0) { |
| 2454 unlink.Jump(); | 2480 unlink.Jump(); |
| 2455 } | 2481 } |
| 2456 } | 2482 } |
| 2457 | 2483 |
| 2458 // Generate code to set the state for the (formerly) shadowing targets that | 2484 // Generate code to set the state for the (formerly) shadowing targets that |
| 2459 // have been jumped to. | 2485 // have been jumped to. |
| 2460 for (int i = 0; i <= nof_escapes; i++) { | 2486 for (int i = 0; i <= nof_escapes; i++) { |
| 2461 if (shadows[i]->is_linked()) { | 2487 if (shadows[i]->is_linked()) { |
| 2462 // Because we can be jumping here (to spilled code) from unspilled | 2488 // Because we can be jumping here (to spilled code) from |
| 2463 // code, we need to reestablish a spilled frame at this block. | 2489 // unspilled code, we need to reestablish a spilled frame at |
| 2490 // this block. | |
| 2464 shadows[i]->Bind(); | 2491 shadows[i]->Bind(); |
| 2465 frame_->SpillAll(); | 2492 frame_->SpillAll(); |
| 2466 if (shadows[i]->original_target() == &function_return_) { | 2493 if (i == kReturnShadowIndex) { |
| 2467 // If this target shadowed the function return, materialize the | 2494 // If this target shadowed the function return, materialize |
| 2468 // return value on the stack. | 2495 // the return value on the stack. |
| 2469 frame_->EmitPush(eax); | 2496 frame_->EmitPush(eax); |
| 2470 } else { | 2497 } else { |
| 2471 // Fake TOS for targets that shadowed breaks and continues. | 2498 // Fake TOS for targets that shadowed breaks and continues. |
| 2472 frame_->EmitPush(Immediate(Factory::undefined_value())); | 2499 frame_->EmitPush(Immediate(Factory::undefined_value())); |
| 2473 } | 2500 } |
| 2474 __ Set(ecx, Immediate(Smi::FromInt(JUMPING + i))); | 2501 __ Set(ecx, Immediate(Smi::FromInt(JUMPING + i))); |
| 2475 unlink.Jump(); | 2502 unlink.Jump(); |
| 2476 } | 2503 } |
| 2477 } | 2504 } |
| 2478 | 2505 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2511 VisitStatementsAndSpill(node->finally_block()->statements()); | 2538 VisitStatementsAndSpill(node->finally_block()->statements()); |
| 2512 | 2539 |
| 2513 break_stack_height_ -= kFinallyStackSize; | 2540 break_stack_height_ -= kFinallyStackSize; |
| 2514 if (has_valid_frame()) { | 2541 if (has_valid_frame()) { |
| 2515 JumpTarget exit(this); | 2542 JumpTarget exit(this); |
| 2516 // Restore state and return value or faked TOS. | 2543 // Restore state and return value or faked TOS. |
| 2517 frame_->EmitPop(ecx); | 2544 frame_->EmitPop(ecx); |
| 2518 frame_->EmitPop(eax); | 2545 frame_->EmitPop(eax); |
| 2519 | 2546 |
| 2520 // Generate code to jump to the right destination for all used | 2547 // Generate code to jump to the right destination for all used |
| 2521 // (formerly) shadowing targets. | 2548 // formerly shadowing targets. |
| 2522 for (int i = 0; i <= nof_escapes; i++) { | 2549 for (int i = 0; i <= nof_escapes; i++) { |
| 2523 if (shadows[i]->is_bound()) { | 2550 if (shadows[i]->is_bound()) { |
| 2551 JumpTarget* original = shadows[i]->original_target(); | |
| 2524 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); | 2552 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); |
| 2525 shadows[i]->original_target()->Branch(equal); | 2553 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { |
| 2554 JumpTarget skip(this); | |
| 2555 skip.Branch(not_equal); | |
| 2556 frame_->PrepareForReturn(); | |
| 2557 original->Jump(); | |
| 2558 skip.Bind(); | |
| 2559 } else { | |
| 2560 original->Branch(equal); | |
| 2561 } | |
| 2526 } | 2562 } |
| 2527 } | 2563 } |
| 2528 | 2564 |
| 2529 // Check if we need to rethrow the exception. | 2565 // Check if we need to rethrow the exception. |
| 2530 __ cmp(Operand(ecx), Immediate(Smi::FromInt(THROWING))); | 2566 __ cmp(Operand(ecx), Immediate(Smi::FromInt(THROWING))); |
| 2531 exit.Branch(not_equal); | 2567 exit.Branch(not_equal); |
| 2532 | 2568 |
| 2533 // Rethrow exception. | 2569 // Rethrow exception. |
| 2534 frame_->EmitPush(eax); // undo pop from above | 2570 frame_->EmitPush(eax); // undo pop from above |
| 2535 frame_->CallRuntime(Runtime::kReThrow, 1); | 2571 frame_->CallRuntime(Runtime::kReThrow, 1); |
| (...skipping 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4293 SmiComparison(cc, right->AsLiteral()->handle(), strict); | 4329 SmiComparison(cc, right->AsLiteral()->handle(), strict); |
| 4294 return; | 4330 return; |
| 4295 } | 4331 } |
| 4296 | 4332 |
| 4297 Load(left); | 4333 Load(left); |
| 4298 Load(right); | 4334 Load(right); |
| 4299 Comparison(cc, strict); | 4335 Comparison(cc, strict); |
| 4300 } | 4336 } |
| 4301 | 4337 |
| 4302 | 4338 |
| 4303 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { | |
| 4304 return (target == &function_return_ && !function_return_is_shadowed_); | |
| 4305 } | |
| 4306 | |
| 4307 | |
| 4308 #ifdef DEBUG | 4339 #ifdef DEBUG |
| 4309 bool CodeGenerator::HasValidEntryRegisters() { | 4340 bool CodeGenerator::HasValidEntryRegisters() { |
| 4310 return (allocator()->count(eax) - frame()->register_count(eax) == 0) | 4341 return (allocator()->count(eax) == frame()->register_count(eax)) |
| 4311 && (allocator()->count(ebx) - frame()->register_count(ebx) == 0) | 4342 && (allocator()->count(ebx) == frame()->register_count(ebx)) |
| 4312 && (allocator()->count(ecx) - frame()->register_count(ecx) == 0) | 4343 && (allocator()->count(ecx) == frame()->register_count(ecx)) |
| 4313 && (allocator()->count(edx) - frame()->register_count(edx) == 0) | 4344 && (allocator()->count(edx) == frame()->register_count(edx)) |
| 4314 && (allocator()->count(edi) - frame()->register_count(edi) == 0); | 4345 && (allocator()->count(edi) == frame()->register_count(edi)); |
| 4315 } | 4346 } |
| 4316 #endif | 4347 #endif |
| 4317 | 4348 |
| 4318 | 4349 |
| 4319 class DeferredReferenceGetKeyedValue: public DeferredCode { | 4350 class DeferredReferenceGetKeyedValue: public DeferredCode { |
| 4320 public: | 4351 public: |
| 4321 DeferredReferenceGetKeyedValue(CodeGenerator* generator, bool is_global) | 4352 DeferredReferenceGetKeyedValue(CodeGenerator* generator, bool is_global) |
| 4322 : DeferredCode(generator), is_global_(is_global) { | 4353 : DeferredCode(generator), is_global_(is_global) { |
| 4323 set_comment("[ DeferredReferenceGetKeyedValue"); | 4354 set_comment("[ DeferredReferenceGetKeyedValue"); |
| 4324 } | 4355 } |
| (...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5944 | 5975 |
| 5945 // Slow-case: Go through the JavaScript implementation. | 5976 // Slow-case: Go through the JavaScript implementation. |
| 5946 __ bind(&slow); | 5977 __ bind(&slow); |
| 5947 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5978 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 5948 } | 5979 } |
| 5949 | 5980 |
| 5950 | 5981 |
| 5951 #undef __ | 5982 #undef __ |
| 5952 | 5983 |
| 5953 } } // namespace v8::internal | 5984 } } // namespace v8::internal |
| OLD | NEW |