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