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

Side by Side Diff: src/isolate.cc

Issue 20680002: Rebase of partial ia32 implementation of optimized try/catch (started by Kevin Millikin, continued … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix detection of CATCH frames (fixes debuger exception reporting anf breaks another assertion...). Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/isolate.h ('k') | src/lithium.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 current_vm_state_ = EXTERNAL; 96 current_vm_state_ = EXTERNAL;
97 try_catch_handler_address_ = NULL; 97 try_catch_handler_address_ = NULL;
98 context_ = NULL; 98 context_ = NULL;
99 thread_id_ = ThreadId::Invalid(); 99 thread_id_ = ThreadId::Invalid();
100 external_caught_exception_ = false; 100 external_caught_exception_ = false;
101 failed_access_check_callback_ = NULL; 101 failed_access_check_callback_ = NULL;
102 save_context_ = NULL; 102 save_context_ = NULL;
103 catcher_ = NULL; 103 catcher_ = NULL;
104 top_lookup_result_ = NULL; 104 top_lookup_result_ = NULL;
105 105
106 optimized_handler_patch_buffer_ = NULL;
107 optimized_pending_exception_ = NULL;
108 optimized_handler_handler_index_ = -1;
109 optimized_handler_deopt_index_ = -1;
110 optimized_handler_frame_pc_offset_ = -1;
111
106 // These members are re-initialized later after deserialization 112 // These members are re-initialized later after deserialization
107 // is complete. 113 // is complete.
108 pending_exception_ = NULL; 114 pending_exception_ = NULL;
109 has_pending_message_ = false; 115 has_pending_message_ = false;
110 pending_message_obj_ = NULL; 116 pending_message_obj_ = NULL;
111 pending_message_script_ = NULL; 117 pending_message_script_ = NULL;
112 scheduled_exception_ = NULL; 118 scheduled_exception_ = NULL;
113 } 119 }
114 120
115 121
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 DoThrow(exception, location); 1133 DoThrow(exception, location);
1128 return Failure::Exception(); 1134 return Failure::Exception();
1129 } 1135 }
1130 1136
1131 1137
1132 Failure* Isolate::ReThrow(MaybeObject* exception) { 1138 Failure* Isolate::ReThrow(MaybeObject* exception) {
1133 bool can_be_caught_externally = false; 1139 bool can_be_caught_externally = false;
1134 bool catchable_by_javascript = is_catchable_by_javascript(exception); 1140 bool catchable_by_javascript = is_catchable_by_javascript(exception);
1135 ShouldReportException(&can_be_caught_externally, catchable_by_javascript); 1141 ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
1136 1142
1137 thread_local_top()->catcher_ = can_be_caught_externally ? 1143 thread_local_top()->catcher_ =
1138 try_catch_handler() : NULL; 1144 can_be_caught_externally ? try_catch_handler() : NULL;
1139 1145
1140 // Set the exception being re-thrown. 1146 // Set the exception being re-thrown.
1141 set_pending_exception(exception); 1147 set_pending_exception(exception);
1142 if (exception->IsFailure()) return exception->ToFailureUnchecked(); 1148
1143 return Failure::Exception(); 1149 // Try to prepare the optimized code for catching only if there is not
1150 // an optimized handler ready to catch from the previous throw.
1151 if (!is_handling_optimized_catch_statement()) {
1152 PrepareForOptimizedHandler();
1153 }
1154
1155 return exception->IsFailure()
1156 ? exception->ToFailureUnchecked()
1157 : Failure::Exception();
1144 } 1158 }
1145 1159
1146 1160
1147 Failure* Isolate::ThrowIllegalOperation() { 1161 Failure* Isolate::ThrowIllegalOperation() {
1148 return Throw(heap_.illegal_access_string()); 1162 return Throw(heap_.illegal_access_string());
1149 } 1163 }
1150 1164
1151 1165
1152 void Isolate::ScheduleThrow(Object* exception) { 1166 void Isolate::ScheduleThrow(Object* exception) {
1153 // When scheduling a throw we first throw the exception to get the 1167 // When scheduling a throw we first throw the exception to get the
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 line_number + 1); 1400 line_number + 1);
1387 } 1401 }
1388 } 1402 }
1389 } 1403 }
1390 1404
1391 // Save the message for reporting if the the exception remains uncaught. 1405 // Save the message for reporting if the the exception remains uncaught.
1392 thread_local_top()->has_pending_message_ = report_exception; 1406 thread_local_top()->has_pending_message_ = report_exception;
1393 1407
1394 // Do not forget to clean catcher_ if currently thrown exception cannot 1408 // Do not forget to clean catcher_ if currently thrown exception cannot
1395 // be caught. If necessary, ReThrow will update the catcher. 1409 // be caught. If necessary, ReThrow will update the catcher.
1396 thread_local_top()->catcher_ = can_be_caught_externally ? 1410 thread_local_top()->catcher_ =
1397 try_catch_handler() : NULL; 1411 can_be_caught_externally ? try_catch_handler() : NULL;
1398 1412
1399 set_pending_exception(*exception_handle); 1413 set_pending_exception(*exception_handle);
1414
1415 // If the top-most handler is an optimized JS handler, we need to do
1416 // some work to prepare the optimized code for catching.
1417 PrepareForOptimizedHandler();
1400 } 1418 }
1401 1419
1402 1420
1421 void Isolate::PrepareForOptimizedHandler() {
1422 // Look for the topmost handler that is not a of kind JS_ENTRY
1423 Address js_handler_address = Isolate::handler(thread_local_top());
1424 StackHandler* handler = StackHandler::FromAddress(js_handler_address);
1425 while (handler != NULL && handler->is_js_entry()) {
1426 handler = handler->next();
1427 }
1428 // There might not be a JS handler at all.
1429 if (handler == NULL) {
1430 return;
1431 }
1432 // There might be an API handler before the top JS handler.
1433 Address api_handler_address = thread_local_top()->try_catch_handler_address();
1434 if (api_handler_address != NULL && api_handler_address < Address(handler)) {
1435 return;
1436 }
1437 // The top JS handler might not be in optimized code.
1438 if (!handler->is_optimized()) {
1439 return;
1440 }
1441
1442 set_optimized_handler_handler_index(handler->index());
1443
1444 // Find the frame corresponding to this handler.
1445 JavaScriptFrame* frame = NULL;
1446 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) {
1447 frame = it.frame();
1448 if (frame->HasHandler() && frame->fp() > Address(handler)) break;
1449 }
1450
1451 // This will be read by the deopt and put into eax.
1452 // FIXME(mmassi): can this be moved by a collection?
1453 set_optimized_pending_exception(pending_exception());
1454
1455 // Set the index of the next safepoint from the current PC.
1456 // Runtime_CatchInOptimizedCode will then use it to find the offset where
1457 // the code needs to be patched.
1458 Code* code = handler->code();
1459 SafepointEntry safepoint = code->GetSafepointEntry(frame->pc());
1460 int deopt_index = safepoint.deoptimization_index();
1461 ASSERT(deopt_index != Safepoint::kNoDeoptimizationIndex);
1462 set_optimized_handler_deopt_index(deopt_index);
1463 // Also set the offset in "code" where we will need to jump to.
1464 set_optimized_handler_frame_pc_offset(
1465 frame->pc() - reinterpret_cast<Address>(code));
1466
1467 }
1468
1469
1470 void Isolate::ClearOptimizedHandlerByDeopt(Code* optimized_code) {
1471 deoptimizer_data()->RemoveDeoptimizingCode(optimized_code);
1472 clear_optimized_handler_handler_index();
1473 clear_optimized_handler_deopt_index();
1474 clear_optimized_handler_patch_buffer();
1475 }
1476
1477
1478 void Isolate::ClearOptimizedHandlerByAPI() {
1479 clear_optimized_handler_handler_index();
1480 clear_optimized_handler_deopt_index();
1481 clear_optimized_handler_frame_pc_offset();
1482 clear_optimized_pending_exception();
1483 }
1484
1485
1403 bool Isolate::IsExternallyCaught() { 1486 bool Isolate::IsExternallyCaught() {
1404 ASSERT(has_pending_exception()); 1487 ASSERT(has_pending_exception());
1405 1488
1406 if ((thread_local_top()->catcher_ == NULL) || 1489 if ((thread_local_top()->catcher_ == NULL) ||
1407 (try_catch_handler() != thread_local_top()->catcher_)) { 1490 (try_catch_handler() != thread_local_top()->catcher_)) {
1408 // When throwing the exception, we found no v8::TryCatch 1491 // When throwing the exception, we found no v8::TryCatch
1409 // which should care about this exception. 1492 // which should care about this exception.
1410 return false; 1493 return false;
1411 } 1494 }
1412 1495
(...skipping 13 matching lines...) Expand all
1426 // There should be no try-catch blocks as they would prohibit us from 1509 // There should be no try-catch blocks as they would prohibit us from
1427 // finding external catcher in the first place (see catcher_ check above). 1510 // finding external catcher in the first place (see catcher_ check above).
1428 // 1511 //
1429 // Note, that finally clause would rethrow an exception unless it's 1512 // Note, that finally clause would rethrow an exception unless it's
1430 // aborted by jumps in control flow like return, break, etc. and we'll 1513 // aborted by jumps in control flow like return, break, etc. and we'll
1431 // have another chances to set proper v8::TryCatch. 1514 // have another chances to set proper v8::TryCatch.
1432 StackHandler* handler = 1515 StackHandler* handler =
1433 StackHandler::FromAddress(Isolate::handler(thread_local_top())); 1516 StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1434 while (handler != NULL && handler->address() < external_handler_address) { 1517 while (handler != NULL && handler->address() < external_handler_address) {
1435 ASSERT(!handler->is_catch()); 1518 ASSERT(!handler->is_catch());
1519 // Despite the above ASSERT the handler could come from optimized code.
1520 if (handler->is_optimized()) return false;
1436 if (handler->is_finally()) return false; 1521 if (handler->is_finally()) return false;
1437 1522
1438 handler = handler->next(); 1523 handler = handler->next();
1439 } 1524 }
1440 1525
1441 return true; 1526 return true;
1442 } 1527 }
1443 1528
1444 1529
1445 void Isolate::ReportPendingMessages() { 1530 void Isolate::ReportPendingMessages() {
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 2019
1935 Isolate::~Isolate() { 2020 Isolate::~Isolate() {
1936 TRACE_ISOLATE(destructor); 2021 TRACE_ISOLATE(destructor);
1937 2022
1938 // Has to be called while counters_ are still alive. 2023 // Has to be called while counters_ are still alive.
1939 runtime_zone_.DeleteKeptSegment(); 2024 runtime_zone_.DeleteKeptSegment();
1940 2025
1941 delete[] assembler_spare_buffer_; 2026 delete[] assembler_spare_buffer_;
1942 assembler_spare_buffer_ = NULL; 2027 assembler_spare_buffer_ = NULL;
1943 2028
2029 // FIXME(mmassi): why there was no guard here?
2030 if (optimized_handler_patch_buffer() != NULL) {
2031 clear_optimized_handler_patch_buffer();
2032 }
2033
1944 delete unicode_cache_; 2034 delete unicode_cache_;
1945 unicode_cache_ = NULL; 2035 unicode_cache_ = NULL;
1946 2036
1947 delete date_cache_; 2037 delete date_cache_;
1948 date_cache_ = NULL; 2038 date_cache_ = NULL;
1949 2039
1950 delete[] code_stub_interface_descriptors_; 2040 delete[] code_stub_interface_descriptors_;
1951 code_stub_interface_descriptors_ = NULL; 2041 code_stub_interface_descriptors_ = NULL;
1952 2042
1953 delete regexp_stack_; 2043 delete regexp_stack_;
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
2445 2535
2446 #ifdef DEBUG 2536 #ifdef DEBUG
2447 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ 2537 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \
2448 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); 2538 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
2449 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) 2539 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
2450 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) 2540 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
2451 #undef ISOLATE_FIELD_OFFSET 2541 #undef ISOLATE_FIELD_OFFSET
2452 #endif 2542 #endif
2453 2543
2454 } } // namespace v8::internal 2544 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/isolate.h ('k') | src/lithium.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698