| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |