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 2320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2331 int object_index = deferred_objects_.length() - 1; | 2331 int object_index = deferred_objects_.length() - 1; |
2332 for (int i = 0; i < length; i++) { | 2332 for (int i = 0; i < length; i++) { |
2333 DoTranslateObject(iterator, object_index, i); | 2333 DoTranslateObject(iterator, object_index, i); |
2334 } | 2334 } |
2335 return; | 2335 return; |
2336 } | 2336 } |
2337 } | 2337 } |
2338 } | 2338 } |
2339 | 2339 |
2340 | 2340 |
2341 void Deoptimizer::PatchInterruptCode(Isolate* isolate, | |
2342 Code* unoptimized) { | |
2343 DisallowHeapAllocation no_gc; | |
2344 Code* replacement_code = | |
2345 isolate->builtins()->builtin(Builtins::kOnStackReplacement); | |
2346 | |
2347 // Iterate over the back edge table and patch every interrupt | |
2348 // call to an unconditional call to the replacement code. | |
2349 int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level(); | |
2350 | |
2351 for (FullCodeGenerator::BackEdgeTableIterator back_edges(unoptimized, &no_gc); | |
2352 !back_edges.Done(); | |
2353 back_edges.Next()) { | |
2354 if (static_cast<int>(back_edges.loop_depth()) == loop_nesting_level) { | |
2355 ASSERT_EQ(NOT_PATCHED, GetInterruptPatchState(isolate, | |
2356 unoptimized, | |
2357 back_edges.pc())); | |
2358 PatchInterruptCodeAt(unoptimized, | |
2359 back_edges.pc(), | |
2360 replacement_code); | |
2361 } | |
2362 } | |
2363 | |
2364 unoptimized->set_back_edges_patched_for_osr(true); | |
2365 ASSERT(Deoptimizer::VerifyInterruptCode( | |
2366 isolate, unoptimized, loop_nesting_level)); | |
2367 } | |
2368 | |
2369 | |
2370 void Deoptimizer::RevertInterruptCode(Isolate* isolate, | |
2371 Code* unoptimized) { | |
2372 DisallowHeapAllocation no_gc; | |
2373 Code* interrupt_code = | |
2374 isolate->builtins()->builtin(Builtins::kInterruptCheck); | |
2375 | |
2376 // Iterate over the back edge table and revert the patched interrupt calls. | |
2377 ASSERT(unoptimized->back_edges_patched_for_osr()); | |
2378 int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level(); | |
2379 | |
2380 for (FullCodeGenerator::BackEdgeTableIterator back_edges(unoptimized, &no_gc); | |
2381 !back_edges.Done(); | |
2382 back_edges.Next()) { | |
2383 if (static_cast<int>(back_edges.loop_depth()) <= loop_nesting_level) { | |
2384 ASSERT_EQ(PATCHED_FOR_OSR, GetInterruptPatchState(isolate, | |
2385 unoptimized, | |
2386 back_edges.pc())); | |
2387 RevertInterruptCodeAt(unoptimized, back_edges.pc(), interrupt_code); | |
2388 } | |
2389 } | |
2390 | |
2391 unoptimized->set_back_edges_patched_for_osr(false); | |
2392 unoptimized->set_allow_osr_at_loop_nesting_level(0); | |
2393 // Assert that none of the back edges are patched anymore. | |
2394 ASSERT(Deoptimizer::VerifyInterruptCode(isolate, unoptimized, -1)); | |
2395 } | |
2396 | |
2397 | |
2398 #ifdef DEBUG | |
2399 bool Deoptimizer::VerifyInterruptCode(Isolate* isolate, | |
2400 Code* unoptimized, | |
2401 int loop_nesting_level) { | |
2402 DisallowHeapAllocation no_gc; | |
2403 for (FullCodeGenerator::BackEdgeTableIterator back_edges(unoptimized, &no_gc); | |
2404 !back_edges.Done(); | |
2405 back_edges.Next()) { | |
2406 uint32_t loop_depth = back_edges.loop_depth(); | |
2407 CHECK_LE(static_cast<int>(loop_depth), Code::kMaxLoopNestingMarker); | |
2408 // Assert that all back edges for shallower loops (and only those) | |
2409 // have already been patched. | |
2410 CHECK_EQ((static_cast<int>(loop_depth) <= loop_nesting_level), | |
2411 GetInterruptPatchState(isolate, | |
2412 unoptimized, | |
2413 back_edges.pc()) != NOT_PATCHED); | |
2414 } | |
2415 return true; | |
2416 } | |
2417 #endif // DEBUG | |
2418 | |
2419 | |
2420 unsigned Deoptimizer::ComputeInputFrameSize() const { | 2341 unsigned Deoptimizer::ComputeInputFrameSize() const { |
2421 unsigned fixed_size = ComputeFixedSize(function_); | 2342 unsigned fixed_size = ComputeFixedSize(function_); |
2422 // The fp-to-sp delta already takes the context and the function | 2343 // The fp-to-sp delta already takes the context and the function |
2423 // into account so we have to avoid double counting them (-2). | 2344 // into account so we have to avoid double counting them (-2). |
2424 unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize); | 2345 unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize); |
2425 #ifdef DEBUG | 2346 #ifdef DEBUG |
2426 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { | 2347 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
2427 unsigned stack_slots = compiled_code_->stack_slots(); | 2348 unsigned stack_slots = compiled_code_->stack_slots(); |
2428 unsigned outgoing_size = ComputeOutgoingArgumentSize(); | 2349 unsigned outgoing_size = ComputeOutgoingArgumentSize(); |
2429 ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); | 2350 ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3052 | 2973 |
3053 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 2974 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
3054 v->VisitPointer(BitCast<Object**>(&function_)); | 2975 v->VisitPointer(BitCast<Object**>(&function_)); |
3055 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 2976 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
3056 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 2977 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
3057 } | 2978 } |
3058 | 2979 |
3059 #endif // ENABLE_DEBUGGER_SUPPORT | 2980 #endif // ENABLE_DEBUGGER_SUPPORT |
3060 | 2981 |
3061 } } // namespace v8::internal | 2982 } } // namespace v8::internal |
OLD | NEW |