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

Side by Side Diff: src/isolate.cc

Issue 10910161: Partial ia32 implementation of optimized try/catch (by Kevin Millikin) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed build. Created 8 years, 3 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 current_vm_state_ = EXTERNAL; 94 current_vm_state_ = EXTERNAL;
95 try_catch_handler_address_ = NULL; 95 try_catch_handler_address_ = NULL;
96 context_ = NULL; 96 context_ = NULL;
97 thread_id_ = ThreadId::Invalid(); 97 thread_id_ = ThreadId::Invalid();
98 external_caught_exception_ = false; 98 external_caught_exception_ = false;
99 failed_access_check_callback_ = NULL; 99 failed_access_check_callback_ = NULL;
100 save_context_ = NULL; 100 save_context_ = NULL;
101 catcher_ = NULL; 101 catcher_ = NULL;
102 top_lookup_result_ = NULL; 102 top_lookup_result_ = NULL;
103 103
104 optimized_handler_patch_buffer_ = NULL;
105 optimized_pending_exception_ = NULL;
106 optimized_handler_handler_index_ = -1;
107 optimized_handler_deopt_index_ = -1;
108 optimized_handler_frame_pc_offset_ = -1;
109
104 // These members are re-initialized later after deserialization 110 // These members are re-initialized later after deserialization
105 // is complete. 111 // is complete.
106 pending_exception_ = NULL; 112 pending_exception_ = NULL;
107 has_pending_message_ = false; 113 has_pending_message_ = false;
108 pending_message_obj_ = NULL; 114 pending_message_obj_ = NULL;
109 pending_message_script_ = NULL; 115 pending_message_script_ = NULL;
110 scheduled_exception_ = NULL; 116 scheduled_exception_ = NULL;
111 } 117 }
112 118
113 119
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 DoThrow(exception, location); 952 DoThrow(exception, location);
947 return Failure::Exception(); 953 return Failure::Exception();
948 } 954 }
949 955
950 956
951 Failure* Isolate::ReThrow(MaybeObject* exception) { 957 Failure* Isolate::ReThrow(MaybeObject* exception) {
952 bool can_be_caught_externally = false; 958 bool can_be_caught_externally = false;
953 bool catchable_by_javascript = is_catchable_by_javascript(exception); 959 bool catchable_by_javascript = is_catchable_by_javascript(exception);
954 ShouldReportException(&can_be_caught_externally, catchable_by_javascript); 960 ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
955 961
956 thread_local_top()->catcher_ = can_be_caught_externally ? 962 thread_local_top()->catcher_ =
957 try_catch_handler() : NULL; 963 can_be_caught_externally ? try_catch_handler() : NULL;
958 964
959 // Set the exception being re-thrown. 965 // Set the exception being re-thrown.
960 set_pending_exception(exception); 966 set_pending_exception(exception);
961 if (exception->IsFailure()) return exception->ToFailureUnchecked(); 967
962 return Failure::Exception(); 968 // Try to prepare the optimized code for catching only if there is not
969 // an optimized handler ready to catch from the previous throw.
970 if (!is_handling_optimized_catch_statement()) {
971 PrepareForOptimizedHandler();
972 }
973
974 return exception->IsFailure()
975 ? exception->ToFailureUnchecked()
976 : Failure::Exception();
963 } 977 }
964 978
965 979
966 Failure* Isolate::ThrowIllegalOperation() { 980 Failure* Isolate::ThrowIllegalOperation() {
967 return Throw(heap_.illegal_access_symbol()); 981 return Throw(heap_.illegal_access_symbol());
968 } 982 }
969 983
970 984
971 void Isolate::ScheduleThrow(Object* exception) { 985 void Isolate::ScheduleThrow(Object* exception) {
972 // When scheduling a throw we first throw the exception to get the 986 // When scheduling a throw we first throw the exception to get the
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 line_number + 1); 1185 line_number + 1);
1172 } 1186 }
1173 } 1187 }
1174 } 1188 }
1175 1189
1176 // Save the message for reporting if the the exception remains uncaught. 1190 // Save the message for reporting if the the exception remains uncaught.
1177 thread_local_top()->has_pending_message_ = report_exception; 1191 thread_local_top()->has_pending_message_ = report_exception;
1178 1192
1179 // Do not forget to clean catcher_ if currently thrown exception cannot 1193 // Do not forget to clean catcher_ if currently thrown exception cannot
1180 // be caught. If necessary, ReThrow will update the catcher. 1194 // be caught. If necessary, ReThrow will update the catcher.
1181 thread_local_top()->catcher_ = can_be_caught_externally ? 1195 thread_local_top()->catcher_ =
1182 try_catch_handler() : NULL; 1196 can_be_caught_externally ? try_catch_handler() : NULL;
1183 1197
1184 set_pending_exception(*exception_handle); 1198 set_pending_exception(*exception_handle);
1199
1200 // If the top-most handler is an optimized JS handler, we need to do
1201 // some work to prepare the optimized code for catching.
1202 PrepareForOptimizedHandler();
1185 } 1203 }
1186 1204
1187 1205
1206 void Isolate::PrepareForOptimizedHandler() {
1207 // Look for the topmost handler that is not a of kind JS_ENTRY
1208 Address js_handler_address = Isolate::handler(thread_local_top());
1209 StackHandler* handler = StackHandler::FromAddress(js_handler_address);
1210 while (handler != NULL && handler->is_js_entry()) {
1211 handler = handler->next();
1212 }
1213 // There might not be a JS handler at all.
1214 if (handler == NULL) {
1215 return;
1216 }
1217 // There might be an API handler before the top JS handler.
1218 Address api_handler_address = thread_local_top()->try_catch_handler_address();
1219 if (api_handler_address != NULL && api_handler_address < Address(handler)) {
1220 return;
1221 }
1222 // The top JS handler might not be in optimized code.
1223 if (!handler->is_optimized()) {
1224 return;
1225 }
1226
1227 set_optimized_handler_handler_index(handler->index());
1228
1229 // Find the frame corresponding to this handler.
1230 JavaScriptFrame* frame = NULL;
1231 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) {
1232 frame = it.frame();
1233 if (frame->HasHandler() && frame->fp() > Address(handler)) break;
1234 }
1235
1236 // This will be read by the deopt and put into eax.
1237 // FIXME(mmassi): can this be moved by a collection?
1238 set_optimized_pending_exception(pending_exception());
1239
1240 // Set the index of the next safepoint from the current PC.
1241 // Runtime_CatchInOptimizedCode will then use it to find the offset where
1242 // the code needs to be patched.
1243 Code* code = handler->code();
1244 SafepointEntry safepoint = code->GetSafepointEntry(frame->pc());
1245 int deopt_index = safepoint.deoptimization_index();
1246 ASSERT(deopt_index != Safepoint::kNoDeoptimizationIndex);
1247 set_optimized_handler_deopt_index(deopt_index);
1248 // Also set the offset in "code" where we will need to jump to.
1249 set_optimized_handler_frame_pc_offset(
1250 frame->pc() - reinterpret_cast<Address>(code));
1251 }
1252
1253
1254 void Isolate::ClearOptimizedHandlerByDeopt(Code* optimized_code) {
1255 Deoptimizer::RemoveDeoptimizingCode(optimized_code);
1256 clear_optimized_handler_handler_index();
1257 clear_optimized_handler_deopt_index();
1258 clear_optimized_handler_patch_buffer();
1259 }
1260
1261
1262 void Isolate::ClearOptimizedHandlerByAPI() {
1263 clear_optimized_handler_handler_index();
1264 clear_optimized_handler_deopt_index();
1265 clear_optimized_handler_frame_pc_offset();
1266 clear_optimized_pending_exception();
1267 }
1268
1269
1188 bool Isolate::IsExternallyCaught() { 1270 bool Isolate::IsExternallyCaught() {
1189 ASSERT(has_pending_exception()); 1271 ASSERT(has_pending_exception());
1190 1272
1191 if ((thread_local_top()->catcher_ == NULL) || 1273 if ((thread_local_top()->catcher_ == NULL) ||
1192 (try_catch_handler() != thread_local_top()->catcher_)) { 1274 (try_catch_handler() != thread_local_top()->catcher_)) {
1193 // When throwing the exception, we found no v8::TryCatch 1275 // When throwing the exception, we found no v8::TryCatch
1194 // which should care about this exception. 1276 // which should care about this exception.
1195 return false; 1277 return false;
1196 } 1278 }
1197 1279
(...skipping 13 matching lines...) Expand all
1211 // There should be no try-catch blocks as they would prohibit us from 1293 // There should be no try-catch blocks as they would prohibit us from
1212 // finding external catcher in the first place (see catcher_ check above). 1294 // finding external catcher in the first place (see catcher_ check above).
1213 // 1295 //
1214 // Note, that finally clause would rethrow an exception unless it's 1296 // Note, that finally clause would rethrow an exception unless it's
1215 // aborted by jumps in control flow like return, break, etc. and we'll 1297 // aborted by jumps in control flow like return, break, etc. and we'll
1216 // have another chances to set proper v8::TryCatch. 1298 // have another chances to set proper v8::TryCatch.
1217 StackHandler* handler = 1299 StackHandler* handler =
1218 StackHandler::FromAddress(Isolate::handler(thread_local_top())); 1300 StackHandler::FromAddress(Isolate::handler(thread_local_top()));
1219 while (handler != NULL && handler->address() < external_handler_address) { 1301 while (handler != NULL && handler->address() < external_handler_address) {
1220 ASSERT(!handler->is_catch()); 1302 ASSERT(!handler->is_catch());
1303 // Despite the above ASSERT the handler could come from optimized code.
1304 if (handler->is_optimized()) return false;
1221 if (handler->is_finally()) return false; 1305 if (handler->is_finally()) return false;
1222 1306
1223 handler = handler->next(); 1307 handler = handler->next();
1224 } 1308 }
1225 1309
1226 return true; 1310 return true;
1227 } 1311 }
1228 1312
1229 1313
1230 void Isolate::ReportPendingMessages() { 1314 void Isolate::ReportPendingMessages() {
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1666 1750
1667 Isolate::~Isolate() { 1751 Isolate::~Isolate() {
1668 TRACE_ISOLATE(destructor); 1752 TRACE_ISOLATE(destructor);
1669 1753
1670 // Has to be called while counters_ are still alive. 1754 // Has to be called while counters_ are still alive.
1671 runtime_zone_.DeleteKeptSegment(); 1755 runtime_zone_.DeleteKeptSegment();
1672 1756
1673 delete[] assembler_spare_buffer_; 1757 delete[] assembler_spare_buffer_;
1674 assembler_spare_buffer_ = NULL; 1758 assembler_spare_buffer_ = NULL;
1675 1759
1760 // FIXME(mmassi): why there was no guard here?
1761 if (optimized_handler_patch_buffer() != NULL) {
1762 clear_optimized_handler_patch_buffer();
1763 }
1764
1676 delete unicode_cache_; 1765 delete unicode_cache_;
1677 unicode_cache_ = NULL; 1766 unicode_cache_ = NULL;
1678 1767
1679 delete date_cache_; 1768 delete date_cache_;
1680 date_cache_ = NULL; 1769 date_cache_ = NULL;
1681 1770
1682 delete regexp_stack_; 1771 delete regexp_stack_;
1683 regexp_stack_ = NULL; 1772 regexp_stack_ = NULL;
1684 1773
1685 delete descriptor_lookup_cache_; 1774 delete descriptor_lookup_cache_;
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
2058 2147
2059 #ifdef DEBUG 2148 #ifdef DEBUG
2060 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ 2149 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \
2061 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); 2150 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
2062 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) 2151 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
2063 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) 2152 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
2064 #undef ISOLATE_FIELD_OFFSET 2153 #undef ISOLATE_FIELD_OFFSET
2065 #endif 2154 #endif
2066 2155
2067 } } // namespace v8::internal 2156 } } // 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