| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 if (thread_id == 0) { | 73 if (thread_id == 0) { |
| 74 thread_id = AllocateThreadId(); | 74 thread_id = AllocateThreadId(); |
| 75 Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id); | 75 Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id); |
| 76 } | 76 } |
| 77 return thread_id; | 77 return thread_id; |
| 78 } | 78 } |
| 79 | 79 |
| 80 | 80 |
| 81 ThreadLocalTop::ThreadLocalTop() { | 81 ThreadLocalTop::ThreadLocalTop() { |
| 82 InitializeInternal(); | 82 InitializeInternal(); |
| 83 // This flag may be set using v8::V8::IgnoreOutOfMemoryException() | |
| 84 // before an isolate is initialized. The initialize methods below do | |
| 85 // not touch it to preserve its value. | |
| 86 ignore_out_of_memory_ = false; | |
| 87 } | 83 } |
| 88 | 84 |
| 89 | 85 |
| 90 void ThreadLocalTop::InitializeInternal() { | 86 void ThreadLocalTop::InitializeInternal() { |
| 91 c_entry_fp_ = 0; | 87 c_entry_fp_ = 0; |
| 92 handler_ = 0; | 88 handler_ = 0; |
| 93 #ifdef USE_SIMULATOR | 89 #ifdef USE_SIMULATOR |
| 94 simulator_ = NULL; | 90 simulator_ = NULL; |
| 95 #endif | 91 #endif |
| 96 js_entry_sp_ = NULL; | 92 js_entry_sp_ = NULL; |
| (...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 } | 1262 } |
| 1267 | 1263 |
| 1268 return true; | 1264 return true; |
| 1269 } | 1265 } |
| 1270 | 1266 |
| 1271 | 1267 |
| 1272 void Isolate::ReportPendingMessages() { | 1268 void Isolate::ReportPendingMessages() { |
| 1273 ASSERT(has_pending_exception()); | 1269 ASSERT(has_pending_exception()); |
| 1274 PropagatePendingExceptionToExternalTryCatch(); | 1270 PropagatePendingExceptionToExternalTryCatch(); |
| 1275 | 1271 |
| 1276 // If the pending exception is OutOfMemoryException set out_of_memory in | |
| 1277 // the native context. Note: We have to mark the native context here | |
| 1278 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to | |
| 1279 // set it. | |
| 1280 HandleScope scope(this); | 1272 HandleScope scope(this); |
| 1281 if (thread_local_top_.pending_exception_->IsOutOfMemory()) { | 1273 if (thread_local_top_.pending_exception_ == |
| 1282 context()->mark_out_of_memory(); | |
| 1283 } else if (thread_local_top_.pending_exception_ == | |
| 1284 heap()->termination_exception()) { | 1274 heap()->termination_exception()) { |
| 1285 // Do nothing: if needed, the exception has been already propagated to | 1275 // Do nothing: if needed, the exception has been already propagated to |
| 1286 // v8::TryCatch. | 1276 // v8::TryCatch. |
| 1287 } else { | 1277 } else { |
| 1288 if (thread_local_top_.has_pending_message_) { | 1278 if (thread_local_top_.has_pending_message_) { |
| 1289 thread_local_top_.has_pending_message_ = false; | 1279 thread_local_top_.has_pending_message_ = false; |
| 1290 if (!thread_local_top_.pending_message_obj_->IsTheHole()) { | 1280 if (!thread_local_top_.pending_message_obj_->IsTheHole()) { |
| 1291 HandleScope scope(this); | 1281 HandleScope scope(this); |
| 1292 Handle<Object> message_obj(thread_local_top_.pending_message_obj_, | 1282 Handle<Object> message_obj(thread_local_top_.pending_message_obj_, |
| 1293 this); | 1283 this); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1304 } | 1294 } |
| 1305 } | 1295 } |
| 1306 } | 1296 } |
| 1307 clear_pending_message(); | 1297 clear_pending_message(); |
| 1308 } | 1298 } |
| 1309 | 1299 |
| 1310 | 1300 |
| 1311 MessageLocation Isolate::GetMessageLocation() { | 1301 MessageLocation Isolate::GetMessageLocation() { |
| 1312 ASSERT(has_pending_exception()); | 1302 ASSERT(has_pending_exception()); |
| 1313 | 1303 |
| 1314 if (!thread_local_top_.pending_exception_->IsOutOfMemory() && | 1304 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && |
| 1315 thread_local_top_.pending_exception_ != heap()->termination_exception() && | |
| 1316 thread_local_top_.has_pending_message_ && | 1305 thread_local_top_.has_pending_message_ && |
| 1317 !thread_local_top_.pending_message_obj_->IsTheHole() && | 1306 !thread_local_top_.pending_message_obj_->IsTheHole() && |
| 1318 !thread_local_top_.pending_message_obj_->IsTheHole()) { | 1307 !thread_local_top_.pending_message_obj_->IsTheHole()) { |
| 1319 Handle<Script> script( | 1308 Handle<Script> script( |
| 1320 Script::cast(thread_local_top_.pending_message_script_)); | 1309 Script::cast(thread_local_top_.pending_message_script_)); |
| 1321 int start_pos = thread_local_top_.pending_message_start_pos_; | 1310 int start_pos = thread_local_top_.pending_message_start_pos_; |
| 1322 int end_pos = thread_local_top_.pending_message_end_pos_; | 1311 int end_pos = thread_local_top_.pending_message_end_pos_; |
| 1323 return MessageLocation(script, start_pos, end_pos); | 1312 return MessageLocation(script, start_pos, end_pos); |
| 1324 } | 1313 } |
| 1325 | 1314 |
| 1326 return MessageLocation(); | 1315 return MessageLocation(); |
| 1327 } | 1316 } |
| 1328 | 1317 |
| 1329 | 1318 |
| 1330 bool Isolate::OptionalRescheduleException(bool is_bottom_call) { | 1319 bool Isolate::OptionalRescheduleException(bool is_bottom_call) { |
| 1331 ASSERT(has_pending_exception()); | 1320 ASSERT(has_pending_exception()); |
| 1332 PropagatePendingExceptionToExternalTryCatch(); | 1321 PropagatePendingExceptionToExternalTryCatch(); |
| 1333 | 1322 |
| 1334 // Always reschedule out of memory exceptions. | 1323 bool is_termination_exception = |
| 1335 if (!is_out_of_memory()) { | 1324 pending_exception() == heap_.termination_exception(); |
| 1336 bool is_termination_exception = | |
| 1337 pending_exception() == heap_.termination_exception(); | |
| 1338 | 1325 |
| 1339 // Do not reschedule the exception if this is the bottom call. | 1326 // Do not reschedule the exception if this is the bottom call. |
| 1340 bool clear_exception = is_bottom_call; | 1327 bool clear_exception = is_bottom_call; |
| 1341 | 1328 |
| 1342 if (is_termination_exception) { | 1329 if (is_termination_exception) { |
| 1343 if (is_bottom_call) { | 1330 if (is_bottom_call) { |
| 1344 thread_local_top()->external_caught_exception_ = false; | |
| 1345 clear_pending_exception(); | |
| 1346 return false; | |
| 1347 } | |
| 1348 } else if (thread_local_top()->external_caught_exception_) { | |
| 1349 // If the exception is externally caught, clear it if there are no | |
| 1350 // JavaScript frames on the way to the C++ frame that has the | |
| 1351 // external handler. | |
| 1352 ASSERT(thread_local_top()->try_catch_handler_address() != NULL); | |
| 1353 Address external_handler_address = | |
| 1354 thread_local_top()->try_catch_handler_address(); | |
| 1355 JavaScriptFrameIterator it(this); | |
| 1356 if (it.done() || (it.frame()->sp() > external_handler_address)) { | |
| 1357 clear_exception = true; | |
| 1358 } | |
| 1359 } | |
| 1360 | |
| 1361 // Clear the exception if needed. | |
| 1362 if (clear_exception) { | |
| 1363 thread_local_top()->external_caught_exception_ = false; | 1331 thread_local_top()->external_caught_exception_ = false; |
| 1364 clear_pending_exception(); | 1332 clear_pending_exception(); |
| 1365 return false; | 1333 return false; |
| 1366 } | 1334 } |
| 1335 } else if (thread_local_top()->external_caught_exception_) { |
| 1336 // If the exception is externally caught, clear it if there are no |
| 1337 // JavaScript frames on the way to the C++ frame that has the |
| 1338 // external handler. |
| 1339 ASSERT(thread_local_top()->try_catch_handler_address() != NULL); |
| 1340 Address external_handler_address = |
| 1341 thread_local_top()->try_catch_handler_address(); |
| 1342 JavaScriptFrameIterator it(this); |
| 1343 if (it.done() || (it.frame()->sp() > external_handler_address)) { |
| 1344 clear_exception = true; |
| 1345 } |
| 1346 } |
| 1347 |
| 1348 // Clear the exception if needed. |
| 1349 if (clear_exception) { |
| 1350 thread_local_top()->external_caught_exception_ = false; |
| 1351 clear_pending_exception(); |
| 1352 return false; |
| 1367 } | 1353 } |
| 1368 | 1354 |
| 1369 // Reschedule the exception. | 1355 // Reschedule the exception. |
| 1370 thread_local_top()->scheduled_exception_ = pending_exception(); | 1356 thread_local_top()->scheduled_exception_ = pending_exception(); |
| 1371 clear_pending_exception(); | 1357 clear_pending_exception(); |
| 1372 return true; | 1358 return true; |
| 1373 } | 1359 } |
| 1374 | 1360 |
| 1375 | 1361 |
| 1376 void Isolate::SetCaptureStackTraceForUncaughtExceptions( | 1362 void Isolate::SetCaptureStackTraceForUncaughtExceptions( |
| 1377 bool capture, | 1363 bool capture, |
| 1378 int frame_limit, | 1364 int frame_limit, |
| 1379 StackTrace::StackTraceOptions options) { | 1365 StackTrace::StackTraceOptions options) { |
| 1380 capture_stack_trace_for_uncaught_exceptions_ = capture; | 1366 capture_stack_trace_for_uncaught_exceptions_ = capture; |
| 1381 stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit; | 1367 stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit; |
| 1382 stack_trace_for_uncaught_exceptions_options_ = options; | 1368 stack_trace_for_uncaught_exceptions_options_ = options; |
| 1383 } | 1369 } |
| 1384 | 1370 |
| 1385 | 1371 |
| 1386 bool Isolate::is_out_of_memory() { | |
| 1387 if (has_pending_exception()) { | |
| 1388 MaybeObject* e = pending_exception(); | |
| 1389 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) { | |
| 1390 return true; | |
| 1391 } | |
| 1392 } | |
| 1393 if (has_scheduled_exception()) { | |
| 1394 MaybeObject* e = scheduled_exception(); | |
| 1395 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) { | |
| 1396 return true; | |
| 1397 } | |
| 1398 } | |
| 1399 return false; | |
| 1400 } | |
| 1401 | |
| 1402 | |
| 1403 Handle<Context> Isolate::native_context() { | 1372 Handle<Context> Isolate::native_context() { |
| 1404 return Handle<Context>(context()->global_object()->native_context()); | 1373 return Handle<Context>(context()->global_object()->native_context()); |
| 1405 } | 1374 } |
| 1406 | 1375 |
| 1407 | 1376 |
| 1408 Handle<Context> Isolate::global_context() { | 1377 Handle<Context> Isolate::global_context() { |
| 1409 return Handle<Context>(context()->global_object()->global_context()); | 1378 return Handle<Context>(context()->global_object()->global_context()); |
| 1410 } | 1379 } |
| 1411 | 1380 |
| 1412 | 1381 |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1844 | 1813 |
| 1845 | 1814 |
| 1846 void Isolate::PropagatePendingExceptionToExternalTryCatch() { | 1815 void Isolate::PropagatePendingExceptionToExternalTryCatch() { |
| 1847 ASSERT(has_pending_exception()); | 1816 ASSERT(has_pending_exception()); |
| 1848 | 1817 |
| 1849 bool external_caught = IsExternallyCaught(); | 1818 bool external_caught = IsExternallyCaught(); |
| 1850 thread_local_top_.external_caught_exception_ = external_caught; | 1819 thread_local_top_.external_caught_exception_ = external_caught; |
| 1851 | 1820 |
| 1852 if (!external_caught) return; | 1821 if (!external_caught) return; |
| 1853 | 1822 |
| 1854 if (thread_local_top_.pending_exception_->IsOutOfMemory()) { | 1823 if (thread_local_top_.pending_exception_ == |
| 1855 // Do not propagate OOM exception: we should kill VM asap. | |
| 1856 } else if (thread_local_top_.pending_exception_ == | |
| 1857 heap()->termination_exception()) { | 1824 heap()->termination_exception()) { |
| 1858 try_catch_handler()->can_continue_ = false; | 1825 try_catch_handler()->can_continue_ = false; |
| 1859 try_catch_handler()->has_terminated_ = true; | 1826 try_catch_handler()->has_terminated_ = true; |
| 1860 try_catch_handler()->exception_ = heap()->null_value(); | 1827 try_catch_handler()->exception_ = heap()->null_value(); |
| 1861 } else { | 1828 } else { |
| 1862 v8::TryCatch* handler = try_catch_handler(); | 1829 v8::TryCatch* handler = try_catch_handler(); |
| 1863 // At this point all non-object (failure) exceptions have | 1830 // At this point all non-object (failure) exceptions have |
| 1864 // been dealt with so this shouldn't fail. | 1831 // been dealt with so this shouldn't fail. |
| 1865 ASSERT(!pending_exception()->IsFailure()); | 1832 ASSERT(!pending_exception()->IsFailure()); |
| 1866 ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() || | 1833 ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() || |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2323 | 2290 |
| 2324 #ifdef DEBUG | 2291 #ifdef DEBUG |
| 2325 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ | 2292 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ |
| 2326 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); | 2293 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); |
| 2327 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) | 2294 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) |
| 2328 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) | 2295 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) |
| 2329 #undef ISOLATE_FIELD_OFFSET | 2296 #undef ISOLATE_FIELD_OFFSET |
| 2330 #endif | 2297 #endif |
| 2331 | 2298 |
| 2332 } } // namespace v8::internal | 2299 } } // namespace v8::internal |
| OLD | NEW |