OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2419 *input_offset -= kPointerSize; | 2419 *input_offset -= kPointerSize; |
2420 return true; | 2420 return true; |
2421 } | 2421 } |
2422 | 2422 |
2423 | 2423 |
2424 void Deoptimizer::PatchInterruptCode(Code* unoptimized_code, | 2424 void Deoptimizer::PatchInterruptCode(Code* unoptimized_code, |
2425 Code* interrupt_code, | 2425 Code* interrupt_code, |
2426 Code* replacement_code) { | 2426 Code* replacement_code) { |
2427 // Iterate over the back edge table and patch every interrupt | 2427 // Iterate over the back edge table and patch every interrupt |
2428 // call to an unconditional call to the replacement code. | 2428 // call to an unconditional call to the replacement code. |
2429 ASSERT(unoptimized_code->kind() == Code::FUNCTION); | |
2430 int loop_nesting_level = unoptimized_code->allow_osr_at_loop_nesting_level(); | 2429 int loop_nesting_level = unoptimized_code->allow_osr_at_loop_nesting_level(); |
2431 Address back_edge_cursor = unoptimized_code->instruction_start() + | 2430 |
2432 unoptimized_code->back_edge_table_offset(); | 2431 for (FullCodeGenerator::BackEdgeTableIterator back_edges(unoptimized_code); |
2433 uint32_t table_length = Memory::uint32_at(back_edge_cursor); | 2432 !back_edges.Done(); |
2434 back_edge_cursor += kIntSize; | 2433 back_edges.Next()) { |
2435 for (uint32_t i = 0; i < table_length; ++i) { | 2434 if (static_cast<int>(back_edges.loop_depth()) == loop_nesting_level) { |
2436 uint32_t loop_depth = Memory::uint32_at(back_edge_cursor + 2 * kIntSize); | |
2437 if (static_cast<int>(loop_depth) == loop_nesting_level) { | |
2438 // Loop back edge has the loop depth that we want to patch. | |
2439 uint32_t pc_offset = Memory::uint32_at(back_edge_cursor + kIntSize); | |
2440 Address pc_after = unoptimized_code->instruction_start() + pc_offset; | |
2441 PatchInterruptCodeAt(unoptimized_code, | 2435 PatchInterruptCodeAt(unoptimized_code, |
2442 pc_after, | 2436 back_edges.pc(), |
2443 interrupt_code, | 2437 interrupt_code, |
2444 replacement_code); | 2438 replacement_code); |
2445 } | 2439 } |
2446 back_edge_cursor += FullCodeGenerator::kBackEdgeEntrySize; | |
2447 } | 2440 } |
| 2441 |
2448 unoptimized_code->set_back_edges_patched_for_osr(true); | 2442 unoptimized_code->set_back_edges_patched_for_osr(true); |
2449 #ifdef DEBUG | 2443 #ifdef DEBUG |
2450 Deoptimizer::VerifyInterruptCode( | 2444 Deoptimizer::VerifyInterruptCode( |
2451 unoptimized_code, interrupt_code, replacement_code, loop_nesting_level); | 2445 unoptimized_code, interrupt_code, replacement_code, loop_nesting_level); |
2452 #endif // DEBUG | 2446 #endif // DEBUG |
2453 } | 2447 } |
2454 | 2448 |
2455 | 2449 |
2456 void Deoptimizer::RevertInterruptCode(Code* unoptimized_code, | 2450 void Deoptimizer::RevertInterruptCode(Code* unoptimized_code, |
2457 Code* interrupt_code, | 2451 Code* interrupt_code, |
2458 Code* replacement_code) { | 2452 Code* replacement_code) { |
2459 // Iterate over the back edge table and revert the patched interrupt calls. | 2453 // Iterate over the back edge table and revert the patched interrupt calls. |
2460 ASSERT(unoptimized_code->kind() == Code::FUNCTION); | |
2461 ASSERT(unoptimized_code->back_edges_patched_for_osr()); | 2454 ASSERT(unoptimized_code->back_edges_patched_for_osr()); |
2462 int loop_nesting_level = unoptimized_code->allow_osr_at_loop_nesting_level(); | 2455 int loop_nesting_level = unoptimized_code->allow_osr_at_loop_nesting_level(); |
2463 Address back_edge_cursor = unoptimized_code->instruction_start() + | 2456 |
2464 unoptimized_code->back_edge_table_offset(); | 2457 for (FullCodeGenerator::BackEdgeTableIterator back_edges(unoptimized_code); |
2465 uint32_t table_length = Memory::uint32_at(back_edge_cursor); | 2458 !back_edges.Done(); |
2466 back_edge_cursor += kIntSize; | 2459 back_edges.Next()) { |
2467 for (uint32_t i = 0; i < table_length; ++i) { | 2460 if (static_cast<int>(back_edges.loop_depth()) <= loop_nesting_level) { |
2468 uint32_t loop_depth = Memory::uint32_at(back_edge_cursor + 2 * kIntSize); | |
2469 if (static_cast<int>(loop_depth) <= loop_nesting_level) { | |
2470 uint32_t pc_offset = Memory::uint32_at(back_edge_cursor + kIntSize); | |
2471 Address pc_after = unoptimized_code->instruction_start() + pc_offset; | |
2472 RevertInterruptCodeAt(unoptimized_code, | 2461 RevertInterruptCodeAt(unoptimized_code, |
2473 pc_after, | 2462 back_edges.pc(), |
2474 interrupt_code, | 2463 interrupt_code, |
2475 replacement_code); | 2464 replacement_code); |
2476 } | 2465 } |
2477 back_edge_cursor += FullCodeGenerator::kBackEdgeEntrySize; | |
2478 } | 2466 } |
| 2467 |
2479 unoptimized_code->set_back_edges_patched_for_osr(false); | 2468 unoptimized_code->set_back_edges_patched_for_osr(false); |
2480 unoptimized_code->set_allow_osr_at_loop_nesting_level(0); | 2469 unoptimized_code->set_allow_osr_at_loop_nesting_level(0); |
2481 #ifdef DEBUG | 2470 #ifdef DEBUG |
2482 // Assert that none of the back edges are patched anymore. | 2471 // Assert that none of the back edges are patched anymore. |
2483 Deoptimizer::VerifyInterruptCode( | 2472 Deoptimizer::VerifyInterruptCode( |
2484 unoptimized_code, interrupt_code, replacement_code, -1); | 2473 unoptimized_code, interrupt_code, replacement_code, -1); |
2485 #endif // DEBUG | 2474 #endif // DEBUG |
2486 } | 2475 } |
2487 | 2476 |
2488 | 2477 |
2489 #ifdef DEBUG | 2478 #ifdef DEBUG |
2490 void Deoptimizer::VerifyInterruptCode(Code* unoptimized_code, | 2479 void Deoptimizer::VerifyInterruptCode(Code* unoptimized_code, |
2491 Code* interrupt_code, | 2480 Code* interrupt_code, |
2492 Code* replacement_code, | 2481 Code* replacement_code, |
2493 int loop_nesting_level) { | 2482 int loop_nesting_level) { |
2494 CHECK(unoptimized_code->kind() == Code::FUNCTION); | 2483 for (FullCodeGenerator::BackEdgeTableIterator back_edges(unoptimized_code); |
2495 Address back_edge_cursor = unoptimized_code->instruction_start() + | 2484 !back_edges.Done(); |
2496 unoptimized_code->back_edge_table_offset(); | 2485 back_edges.Next()) { |
2497 uint32_t table_length = Memory::uint32_at(back_edge_cursor); | 2486 uint32_t loop_depth = back_edges.loop_depth(); |
2498 back_edge_cursor += kIntSize; | |
2499 for (uint32_t i = 0; i < table_length; ++i) { | |
2500 uint32_t loop_depth = Memory::uint32_at(back_edge_cursor + 2 * kIntSize); | |
2501 CHECK_LE(static_cast<int>(loop_depth), Code::kMaxLoopNestingMarker); | 2487 CHECK_LE(static_cast<int>(loop_depth), Code::kMaxLoopNestingMarker); |
2502 // Assert that all back edges for shallower loops (and only those) | 2488 // Assert that all back edges for shallower loops (and only those) |
2503 // have already been patched. | 2489 // have already been patched. |
2504 uint32_t pc_offset = Memory::uint32_at(back_edge_cursor + kIntSize); | |
2505 Address pc_after = unoptimized_code->instruction_start() + pc_offset; | |
2506 CHECK_EQ((static_cast<int>(loop_depth) <= loop_nesting_level), | 2490 CHECK_EQ((static_cast<int>(loop_depth) <= loop_nesting_level), |
2507 InterruptCodeIsPatched(unoptimized_code, | 2491 InterruptCodeIsPatched(unoptimized_code, |
2508 pc_after, | 2492 back_edges.pc(), |
2509 interrupt_code, | 2493 interrupt_code, |
2510 replacement_code)); | 2494 replacement_code)); |
2511 back_edge_cursor += FullCodeGenerator::kBackEdgeEntrySize; | |
2512 } | 2495 } |
2513 } | 2496 } |
2514 #endif // DEBUG | 2497 #endif // DEBUG |
2515 | 2498 |
2516 | 2499 |
2517 unsigned Deoptimizer::ComputeInputFrameSize() const { | 2500 unsigned Deoptimizer::ComputeInputFrameSize() const { |
2518 unsigned fixed_size = ComputeFixedSize(function_); | 2501 unsigned fixed_size = ComputeFixedSize(function_); |
2519 // The fp-to-sp delta already takes the context and the function | 2502 // The fp-to-sp delta already takes the context and the function |
2520 // into account so we have to avoid double counting them (-2). | 2503 // into account so we have to avoid double counting them (-2). |
2521 unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize); | 2504 unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize); |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3143 | 3126 |
3144 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 3127 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
3145 v->VisitPointer(BitCast<Object**>(&function_)); | 3128 v->VisitPointer(BitCast<Object**>(&function_)); |
3146 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 3129 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
3147 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 3130 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
3148 } | 3131 } |
3149 | 3132 |
3150 #endif // ENABLE_DEBUGGER_SUPPORT | 3133 #endif // ENABLE_DEBUGGER_SUPPORT |
3151 | 3134 |
3152 } } // namespace v8::internal | 3135 } } // namespace v8::internal |
OLD | NEW |