OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/ast.h" | 9 #include "src/ast.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 EnsureInitialized(); | 115 EnsureInitialized(); |
116 ThreadId thread_id = ThreadId::Current(); | 116 ThreadId thread_id = ThreadId::Current(); |
117 PerIsolateThreadData* per_thread = NULL; | 117 PerIsolateThreadData* per_thread = NULL; |
118 { | 118 { |
119 base::LockGuard<base::Mutex> lock_guard(process_wide_mutex_.Pointer()); | 119 base::LockGuard<base::Mutex> lock_guard(process_wide_mutex_.Pointer()); |
120 per_thread = thread_data_table_->Lookup(this, thread_id); | 120 per_thread = thread_data_table_->Lookup(this, thread_id); |
121 if (per_thread == NULL) { | 121 if (per_thread == NULL) { |
122 per_thread = new PerIsolateThreadData(this, thread_id); | 122 per_thread = new PerIsolateThreadData(this, thread_id); |
123 thread_data_table_->Insert(per_thread); | 123 thread_data_table_->Insert(per_thread); |
124 } | 124 } |
125 ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread); | 125 DCHECK(thread_data_table_->Lookup(this, thread_id) == per_thread); |
126 } | 126 } |
127 return per_thread; | 127 return per_thread; |
128 } | 128 } |
129 | 129 |
130 | 130 |
131 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() { | 131 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() { |
132 ThreadId thread_id = ThreadId::Current(); | 132 ThreadId thread_id = ThreadId::Current(); |
133 return FindPerThreadDataForThread(thread_id); | 133 return FindPerThreadDataForThread(thread_id); |
134 } | 134 } |
135 | 135 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 } | 242 } |
243 #endif // DEBUG | 243 #endif // DEBUG |
244 | 244 |
245 | 245 |
246 void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) { | 246 void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) { |
247 thread_local_top()->set_try_catch_handler(that); | 247 thread_local_top()->set_try_catch_handler(that); |
248 } | 248 } |
249 | 249 |
250 | 250 |
251 void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) { | 251 void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) { |
252 ASSERT(thread_local_top()->try_catch_handler() == that); | 252 DCHECK(thread_local_top()->try_catch_handler() == that); |
253 thread_local_top()->set_try_catch_handler(that->next_); | 253 thread_local_top()->set_try_catch_handler(that->next_); |
254 thread_local_top()->catcher_ = NULL; | 254 thread_local_top()->catcher_ = NULL; |
255 } | 255 } |
256 | 256 |
257 | 257 |
258 Handle<String> Isolate::StackTraceString() { | 258 Handle<String> Isolate::StackTraceString() { |
259 if (stack_trace_nesting_level_ == 0) { | 259 if (stack_trace_nesting_level_ == 0) { |
260 stack_trace_nesting_level_++; | 260 stack_trace_nesting_level_++; |
261 HeapStringAllocator allocator; | 261 HeapStringAllocator allocator; |
262 StringStream::ClearMentionedObjectCache(this); | 262 StringStream::ClearMentionedObjectCache(this); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 | 336 |
337 Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object, | 337 Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object, |
338 Handle<Object> caller) { | 338 Handle<Object> caller) { |
339 // Get stack trace limit. | 339 // Get stack trace limit. |
340 Handle<Object> error = Object::GetProperty( | 340 Handle<Object> error = Object::GetProperty( |
341 this, js_builtins_object(), "$Error").ToHandleChecked(); | 341 this, js_builtins_object(), "$Error").ToHandleChecked(); |
342 if (!error->IsJSObject()) return factory()->undefined_value(); | 342 if (!error->IsJSObject()) return factory()->undefined_value(); |
343 | 343 |
344 Handle<String> stackTraceLimit = | 344 Handle<String> stackTraceLimit = |
345 factory()->InternalizeUtf8String("stackTraceLimit"); | 345 factory()->InternalizeUtf8String("stackTraceLimit"); |
346 ASSERT(!stackTraceLimit.is_null()); | 346 DCHECK(!stackTraceLimit.is_null()); |
347 Handle<Object> stack_trace_limit = | 347 Handle<Object> stack_trace_limit = |
348 JSObject::GetDataProperty(Handle<JSObject>::cast(error), | 348 JSObject::GetDataProperty(Handle<JSObject>::cast(error), |
349 stackTraceLimit); | 349 stackTraceLimit); |
350 if (!stack_trace_limit->IsNumber()) return factory()->undefined_value(); | 350 if (!stack_trace_limit->IsNumber()) return factory()->undefined_value(); |
351 int limit = FastD2IChecked(stack_trace_limit->Number()); | 351 int limit = FastD2IChecked(stack_trace_limit->Number()); |
352 limit = Max(limit, 0); // Ensure that limit is not negative. | 352 limit = Max(limit, 0); // Ensure that limit is not negative. |
353 | 353 |
354 int initial_size = Min(limit, 10); | 354 int initial_size = Min(limit, 10); |
355 Handle<FixedArray> elements = | 355 Handle<FixedArray> elements = |
356 factory()->NewFixedArrayWithHoles(initial_size * 4 + 1); | 356 factory()->NewFixedArrayWithHoles(initial_size * 4 + 1); |
(...skipping 23 matching lines...) Expand all Loading... |
380 if (!this->context()->HasSameSecurityTokenAs(fun->context())) continue; | 380 if (!this->context()->HasSameSecurityTokenAs(fun->context())) continue; |
381 if (cursor + 4 > elements->length()) { | 381 if (cursor + 4 > elements->length()) { |
382 int new_capacity = JSObject::NewElementsCapacity(elements->length()); | 382 int new_capacity = JSObject::NewElementsCapacity(elements->length()); |
383 Handle<FixedArray> new_elements = | 383 Handle<FixedArray> new_elements = |
384 factory()->NewFixedArrayWithHoles(new_capacity); | 384 factory()->NewFixedArrayWithHoles(new_capacity); |
385 for (int i = 0; i < cursor; i++) { | 385 for (int i = 0; i < cursor; i++) { |
386 new_elements->set(i, elements->get(i)); | 386 new_elements->set(i, elements->get(i)); |
387 } | 387 } |
388 elements = new_elements; | 388 elements = new_elements; |
389 } | 389 } |
390 ASSERT(cursor + 4 <= elements->length()); | 390 DCHECK(cursor + 4 <= elements->length()); |
391 | 391 |
392 | 392 |
393 Handle<Code> code = frames[i].code(); | 393 Handle<Code> code = frames[i].code(); |
394 Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this); | 394 Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this); |
395 // The stack trace API should not expose receivers and function | 395 // The stack trace API should not expose receivers and function |
396 // objects on frames deeper than the top-most one with a strict | 396 // objects on frames deeper than the top-most one with a strict |
397 // mode function. The number of sloppy frames is stored as | 397 // mode function. The number of sloppy frames is stored as |
398 // first element in the result array. | 398 // first element in the result array. |
399 if (!encountered_strict_function) { | 399 if (!encountered_strict_function) { |
400 if (fun->shared()->strict_mode() == STRICT) { | 400 if (fun->shared()->strict_mode() == STRICT) { |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 void Isolate::PrintStack(StringStream* accumulator) { | 592 void Isolate::PrintStack(StringStream* accumulator) { |
593 if (!IsInitialized()) { | 593 if (!IsInitialized()) { |
594 accumulator->Add( | 594 accumulator->Add( |
595 "\n==== JS stack trace is not available =======================\n\n"); | 595 "\n==== JS stack trace is not available =======================\n\n"); |
596 accumulator->Add( | 596 accumulator->Add( |
597 "\n==== Isolate for the thread is not initialized =============\n\n"); | 597 "\n==== Isolate for the thread is not initialized =============\n\n"); |
598 return; | 598 return; |
599 } | 599 } |
600 // The MentionedObjectCache is not GC-proof at the moment. | 600 // The MentionedObjectCache is not GC-proof at the moment. |
601 DisallowHeapAllocation no_gc; | 601 DisallowHeapAllocation no_gc; |
602 ASSERT(StringStream::IsMentionedObjectCacheClear(this)); | 602 DCHECK(StringStream::IsMentionedObjectCacheClear(this)); |
603 | 603 |
604 // Avoid printing anything if there are no frames. | 604 // Avoid printing anything if there are no frames. |
605 if (c_entry_fp(thread_local_top()) == 0) return; | 605 if (c_entry_fp(thread_local_top()) == 0) return; |
606 | 606 |
607 accumulator->Add( | 607 accumulator->Add( |
608 "\n==== JS stack trace =========================================\n\n"); | 608 "\n==== JS stack trace =========================================\n\n"); |
609 PrintFrames(this, accumulator, StackFrame::OVERVIEW); | 609 PrintFrames(this, accumulator, StackFrame::OVERVIEW); |
610 | 610 |
611 accumulator->Add( | 611 accumulator->Add( |
612 "\n==== Details ================================================\n\n"); | 612 "\n==== Details ================================================\n\n"); |
(...skipping 24 matching lines...) Expand all Loading... |
637 | 637 |
638 | 638 |
639 void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver, | 639 void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver, |
640 v8::AccessType type) { | 640 v8::AccessType type) { |
641 if (!thread_local_top()->failed_access_check_callback_) { | 641 if (!thread_local_top()->failed_access_check_callback_) { |
642 Handle<String> message = factory()->InternalizeUtf8String("no access"); | 642 Handle<String> message = factory()->InternalizeUtf8String("no access"); |
643 ScheduleThrow(*factory()->NewTypeError(message)); | 643 ScheduleThrow(*factory()->NewTypeError(message)); |
644 return; | 644 return; |
645 } | 645 } |
646 | 646 |
647 ASSERT(receiver->IsAccessCheckNeeded()); | 647 DCHECK(receiver->IsAccessCheckNeeded()); |
648 ASSERT(context()); | 648 DCHECK(context()); |
649 | 649 |
650 // Get the data object from access check info. | 650 // Get the data object from access check info. |
651 HandleScope scope(this); | 651 HandleScope scope(this); |
652 Handle<Object> data; | 652 Handle<Object> data; |
653 { DisallowHeapAllocation no_gc; | 653 { DisallowHeapAllocation no_gc; |
654 AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); | 654 AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); |
655 if (!access_check_info) return; | 655 if (!access_check_info) return; |
656 data = handle(access_check_info->data(), this); | 656 data = handle(access_check_info->data(), this); |
657 } | 657 } |
658 | 658 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 return YES; | 692 return YES; |
693 } | 693 } |
694 | 694 |
695 return UNKNOWN; | 695 return UNKNOWN; |
696 } | 696 } |
697 | 697 |
698 | 698 |
699 bool Isolate::MayNamedAccess(Handle<JSObject> receiver, | 699 bool Isolate::MayNamedAccess(Handle<JSObject> receiver, |
700 Handle<Object> key, | 700 Handle<Object> key, |
701 v8::AccessType type) { | 701 v8::AccessType type) { |
702 ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); | 702 DCHECK(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); |
703 | 703 |
704 // Skip checks for hidden properties access. Note, we do not | 704 // Skip checks for hidden properties access. Note, we do not |
705 // require existence of a context in this case. | 705 // require existence of a context in this case. |
706 if (key.is_identical_to(factory()->hidden_string())) return true; | 706 if (key.is_identical_to(factory()->hidden_string())) return true; |
707 | 707 |
708 // Check for compatibility between the security tokens in the | 708 // Check for compatibility between the security tokens in the |
709 // current lexical context and the accessed object. | 709 // current lexical context and the accessed object. |
710 ASSERT(context()); | 710 DCHECK(context()); |
711 | 711 |
712 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); | 712 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); |
713 if (decision != UNKNOWN) return decision == YES; | 713 if (decision != UNKNOWN) return decision == YES; |
714 | 714 |
715 HandleScope scope(this); | 715 HandleScope scope(this); |
716 Handle<Object> data; | 716 Handle<Object> data; |
717 v8::NamedSecurityCallback callback; | 717 v8::NamedSecurityCallback callback; |
718 { DisallowHeapAllocation no_gc; | 718 { DisallowHeapAllocation no_gc; |
719 AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); | 719 AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); |
720 if (!access_check_info) return false; | 720 if (!access_check_info) return false; |
(...skipping 10 matching lines...) Expand all Loading... |
731 return callback(v8::Utils::ToLocal(receiver), | 731 return callback(v8::Utils::ToLocal(receiver), |
732 v8::Utils::ToLocal(key), | 732 v8::Utils::ToLocal(key), |
733 type, | 733 type, |
734 v8::Utils::ToLocal(data)); | 734 v8::Utils::ToLocal(data)); |
735 } | 735 } |
736 | 736 |
737 | 737 |
738 bool Isolate::MayIndexedAccess(Handle<JSObject> receiver, | 738 bool Isolate::MayIndexedAccess(Handle<JSObject> receiver, |
739 uint32_t index, | 739 uint32_t index, |
740 v8::AccessType type) { | 740 v8::AccessType type) { |
741 ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); | 741 DCHECK(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); |
742 // Check for compatibility between the security tokens in the | 742 // Check for compatibility between the security tokens in the |
743 // current lexical context and the accessed object. | 743 // current lexical context and the accessed object. |
744 ASSERT(context()); | 744 DCHECK(context()); |
745 | 745 |
746 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); | 746 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); |
747 if (decision != UNKNOWN) return decision == YES; | 747 if (decision != UNKNOWN) return decision == YES; |
748 | 748 |
749 HandleScope scope(this); | 749 HandleScope scope(this); |
750 Handle<Object> data; | 750 Handle<Object> data; |
751 v8::IndexedSecurityCallback callback; | 751 v8::IndexedSecurityCallback callback; |
752 { DisallowHeapAllocation no_gc; | 752 { DisallowHeapAllocation no_gc; |
753 // Get named access check callback | 753 // Get named access check callback |
754 AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); | 754 AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 PropagatePendingExceptionToExternalTryCatch(); | 870 PropagatePendingExceptionToExternalTryCatch(); |
871 if (has_pending_exception()) { | 871 if (has_pending_exception()) { |
872 thread_local_top()->scheduled_exception_ = pending_exception(); | 872 thread_local_top()->scheduled_exception_ = pending_exception(); |
873 thread_local_top()->external_caught_exception_ = false; | 873 thread_local_top()->external_caught_exception_ = false; |
874 clear_pending_exception(); | 874 clear_pending_exception(); |
875 } | 875 } |
876 } | 876 } |
877 | 877 |
878 | 878 |
879 void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) { | 879 void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) { |
880 ASSERT(handler == try_catch_handler()); | 880 DCHECK(handler == try_catch_handler()); |
881 ASSERT(handler->HasCaught()); | 881 DCHECK(handler->HasCaught()); |
882 ASSERT(handler->rethrow_); | 882 DCHECK(handler->rethrow_); |
883 ASSERT(handler->capture_message_); | 883 DCHECK(handler->capture_message_); |
884 Object* message = reinterpret_cast<Object*>(handler->message_obj_); | 884 Object* message = reinterpret_cast<Object*>(handler->message_obj_); |
885 Object* script = reinterpret_cast<Object*>(handler->message_script_); | 885 Object* script = reinterpret_cast<Object*>(handler->message_script_); |
886 ASSERT(message->IsJSMessageObject() || message->IsTheHole()); | 886 DCHECK(message->IsJSMessageObject() || message->IsTheHole()); |
887 ASSERT(script->IsScript() || script->IsTheHole()); | 887 DCHECK(script->IsScript() || script->IsTheHole()); |
888 thread_local_top()->pending_message_obj_ = message; | 888 thread_local_top()->pending_message_obj_ = message; |
889 thread_local_top()->pending_message_script_ = script; | 889 thread_local_top()->pending_message_script_ = script; |
890 thread_local_top()->pending_message_start_pos_ = handler->message_start_pos_; | 890 thread_local_top()->pending_message_start_pos_ = handler->message_start_pos_; |
891 thread_local_top()->pending_message_end_pos_ = handler->message_end_pos_; | 891 thread_local_top()->pending_message_end_pos_ = handler->message_end_pos_; |
892 } | 892 } |
893 | 893 |
894 | 894 |
895 void Isolate::CancelScheduledExceptionFromTryCatch(v8::TryCatch* handler) { | 895 void Isolate::CancelScheduledExceptionFromTryCatch(v8::TryCatch* handler) { |
896 ASSERT(has_scheduled_exception()); | 896 DCHECK(has_scheduled_exception()); |
897 if (scheduled_exception() == handler->exception_) { | 897 if (scheduled_exception() == handler->exception_) { |
898 ASSERT(scheduled_exception() != heap()->termination_exception()); | 898 DCHECK(scheduled_exception() != heap()->termination_exception()); |
899 clear_scheduled_exception(); | 899 clear_scheduled_exception(); |
900 } | 900 } |
901 } | 901 } |
902 | 902 |
903 | 903 |
904 Object* Isolate::PromoteScheduledException() { | 904 Object* Isolate::PromoteScheduledException() { |
905 Object* thrown = scheduled_exception(); | 905 Object* thrown = scheduled_exception(); |
906 clear_scheduled_exception(); | 906 clear_scheduled_exception(); |
907 // Re-throw the exception to avoid getting repeated error reporting. | 907 // Re-throw the exception to avoid getting repeated error reporting. |
908 return ReThrow(thrown); | 908 return ReThrow(thrown); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 *error_constructor) { | 1002 *error_constructor) { |
1003 return true; | 1003 return true; |
1004 } | 1004 } |
1005 } | 1005 } |
1006 return false; | 1006 return false; |
1007 } | 1007 } |
1008 | 1008 |
1009 static int fatal_exception_depth = 0; | 1009 static int fatal_exception_depth = 0; |
1010 | 1010 |
1011 void Isolate::DoThrow(Object* exception, MessageLocation* location) { | 1011 void Isolate::DoThrow(Object* exception, MessageLocation* location) { |
1012 ASSERT(!has_pending_exception()); | 1012 DCHECK(!has_pending_exception()); |
1013 | 1013 |
1014 HandleScope scope(this); | 1014 HandleScope scope(this); |
1015 Handle<Object> exception_handle(exception, this); | 1015 Handle<Object> exception_handle(exception, this); |
1016 | 1016 |
1017 // Determine reporting and whether the exception is caught externally. | 1017 // Determine reporting and whether the exception is caught externally. |
1018 bool catchable_by_javascript = is_catchable_by_javascript(exception); | 1018 bool catchable_by_javascript = is_catchable_by_javascript(exception); |
1019 bool can_be_caught_externally = false; | 1019 bool can_be_caught_externally = false; |
1020 bool should_report_exception = | 1020 bool should_report_exception = |
1021 ShouldReportException(&can_be_caught_externally, catchable_by_javascript); | 1021 ShouldReportException(&can_be_caught_externally, catchable_by_javascript); |
1022 bool report_exception = catchable_by_javascript && should_report_exception; | 1022 bool report_exception = catchable_by_javascript && should_report_exception; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1156 // Do not forget to clean catcher_ if currently thrown exception cannot | 1156 // Do not forget to clean catcher_ if currently thrown exception cannot |
1157 // be caught. If necessary, ReThrow will update the catcher. | 1157 // be caught. If necessary, ReThrow will update the catcher. |
1158 thread_local_top()->catcher_ = can_be_caught_externally ? | 1158 thread_local_top()->catcher_ = can_be_caught_externally ? |
1159 try_catch_handler() : NULL; | 1159 try_catch_handler() : NULL; |
1160 | 1160 |
1161 set_pending_exception(*exception_handle); | 1161 set_pending_exception(*exception_handle); |
1162 } | 1162 } |
1163 | 1163 |
1164 | 1164 |
1165 bool Isolate::HasExternalTryCatch() { | 1165 bool Isolate::HasExternalTryCatch() { |
1166 ASSERT(has_pending_exception()); | 1166 DCHECK(has_pending_exception()); |
1167 | 1167 |
1168 return (thread_local_top()->catcher_ != NULL) && | 1168 return (thread_local_top()->catcher_ != NULL) && |
1169 (try_catch_handler() == thread_local_top()->catcher_); | 1169 (try_catch_handler() == thread_local_top()->catcher_); |
1170 } | 1170 } |
1171 | 1171 |
1172 | 1172 |
1173 bool Isolate::IsFinallyOnTop() { | 1173 bool Isolate::IsFinallyOnTop() { |
1174 // Get the address of the external handler so we can compare the address to | 1174 // Get the address of the external handler so we can compare the address to |
1175 // determine which one is closer to the top of the stack. | 1175 // determine which one is closer to the top of the stack. |
1176 Address external_handler_address = | 1176 Address external_handler_address = |
1177 thread_local_top()->try_catch_handler_address(); | 1177 thread_local_top()->try_catch_handler_address(); |
1178 ASSERT(external_handler_address != NULL); | 1178 DCHECK(external_handler_address != NULL); |
1179 | 1179 |
1180 // The exception has been externally caught if and only if there is | 1180 // The exception has been externally caught if and only if there is |
1181 // an external handler which is on top of the top-most try-finally | 1181 // an external handler which is on top of the top-most try-finally |
1182 // handler. | 1182 // handler. |
1183 // There should be no try-catch blocks as they would prohibit us from | 1183 // There should be no try-catch blocks as they would prohibit us from |
1184 // finding external catcher in the first place (see catcher_ check above). | 1184 // finding external catcher in the first place (see catcher_ check above). |
1185 // | 1185 // |
1186 // Note, that finally clause would rethrow an exception unless it's | 1186 // Note, that finally clause would rethrow an exception unless it's |
1187 // aborted by jumps in control flow like return, break, etc. and we'll | 1187 // aborted by jumps in control flow like return, break, etc. and we'll |
1188 // have another chances to set proper v8::TryCatch. | 1188 // have another chances to set proper v8::TryCatch. |
1189 StackHandler* handler = | 1189 StackHandler* handler = |
1190 StackHandler::FromAddress(Isolate::handler(thread_local_top())); | 1190 StackHandler::FromAddress(Isolate::handler(thread_local_top())); |
1191 while (handler != NULL && handler->address() < external_handler_address) { | 1191 while (handler != NULL && handler->address() < external_handler_address) { |
1192 ASSERT(!handler->is_catch()); | 1192 DCHECK(!handler->is_catch()); |
1193 if (handler->is_finally()) return true; | 1193 if (handler->is_finally()) return true; |
1194 | 1194 |
1195 handler = handler->next(); | 1195 handler = handler->next(); |
1196 } | 1196 } |
1197 | 1197 |
1198 return false; | 1198 return false; |
1199 } | 1199 } |
1200 | 1200 |
1201 | 1201 |
1202 void Isolate::ReportPendingMessages() { | 1202 void Isolate::ReportPendingMessages() { |
1203 ASSERT(has_pending_exception()); | 1203 DCHECK(has_pending_exception()); |
1204 bool can_clear_message = PropagatePendingExceptionToExternalTryCatch(); | 1204 bool can_clear_message = PropagatePendingExceptionToExternalTryCatch(); |
1205 | 1205 |
1206 HandleScope scope(this); | 1206 HandleScope scope(this); |
1207 if (thread_local_top_.pending_exception_ == heap()->termination_exception()) { | 1207 if (thread_local_top_.pending_exception_ == heap()->termination_exception()) { |
1208 // Do nothing: if needed, the exception has been already propagated to | 1208 // Do nothing: if needed, the exception has been already propagated to |
1209 // v8::TryCatch. | 1209 // v8::TryCatch. |
1210 } else { | 1210 } else { |
1211 if (thread_local_top_.has_pending_message_) { | 1211 if (thread_local_top_.has_pending_message_) { |
1212 thread_local_top_.has_pending_message_ = false; | 1212 thread_local_top_.has_pending_message_ = false; |
1213 if (!thread_local_top_.pending_message_obj_->IsTheHole()) { | 1213 if (!thread_local_top_.pending_message_obj_->IsTheHole()) { |
(...skipping 11 matching lines...) Expand all Loading... |
1225 MessageHandler::ReportMessage(this, NULL, message_obj); | 1225 MessageHandler::ReportMessage(this, NULL, message_obj); |
1226 } | 1226 } |
1227 } | 1227 } |
1228 } | 1228 } |
1229 } | 1229 } |
1230 if (can_clear_message) clear_pending_message(); | 1230 if (can_clear_message) clear_pending_message(); |
1231 } | 1231 } |
1232 | 1232 |
1233 | 1233 |
1234 MessageLocation Isolate::GetMessageLocation() { | 1234 MessageLocation Isolate::GetMessageLocation() { |
1235 ASSERT(has_pending_exception()); | 1235 DCHECK(has_pending_exception()); |
1236 | 1236 |
1237 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && | 1237 if (thread_local_top_.pending_exception_ != heap()->termination_exception() && |
1238 thread_local_top_.has_pending_message_ && | 1238 thread_local_top_.has_pending_message_ && |
1239 !thread_local_top_.pending_message_obj_->IsTheHole() && | 1239 !thread_local_top_.pending_message_obj_->IsTheHole() && |
1240 !thread_local_top_.pending_message_obj_->IsTheHole()) { | 1240 !thread_local_top_.pending_message_obj_->IsTheHole()) { |
1241 Handle<Script> script( | 1241 Handle<Script> script( |
1242 Script::cast(thread_local_top_.pending_message_script_)); | 1242 Script::cast(thread_local_top_.pending_message_script_)); |
1243 int start_pos = thread_local_top_.pending_message_start_pos_; | 1243 int start_pos = thread_local_top_.pending_message_start_pos_; |
1244 int end_pos = thread_local_top_.pending_message_end_pos_; | 1244 int end_pos = thread_local_top_.pending_message_end_pos_; |
1245 return MessageLocation(script, start_pos, end_pos); | 1245 return MessageLocation(script, start_pos, end_pos); |
1246 } | 1246 } |
1247 | 1247 |
1248 return MessageLocation(); | 1248 return MessageLocation(); |
1249 } | 1249 } |
1250 | 1250 |
1251 | 1251 |
1252 bool Isolate::OptionalRescheduleException(bool is_bottom_call) { | 1252 bool Isolate::OptionalRescheduleException(bool is_bottom_call) { |
1253 ASSERT(has_pending_exception()); | 1253 DCHECK(has_pending_exception()); |
1254 PropagatePendingExceptionToExternalTryCatch(); | 1254 PropagatePendingExceptionToExternalTryCatch(); |
1255 | 1255 |
1256 bool is_termination_exception = | 1256 bool is_termination_exception = |
1257 pending_exception() == heap_.termination_exception(); | 1257 pending_exception() == heap_.termination_exception(); |
1258 | 1258 |
1259 // Do not reschedule the exception if this is the bottom call. | 1259 // Do not reschedule the exception if this is the bottom call. |
1260 bool clear_exception = is_bottom_call; | 1260 bool clear_exception = is_bottom_call; |
1261 | 1261 |
1262 if (is_termination_exception) { | 1262 if (is_termination_exception) { |
1263 if (is_bottom_call) { | 1263 if (is_bottom_call) { |
1264 thread_local_top()->external_caught_exception_ = false; | 1264 thread_local_top()->external_caught_exception_ = false; |
1265 clear_pending_exception(); | 1265 clear_pending_exception(); |
1266 return false; | 1266 return false; |
1267 } | 1267 } |
1268 } else if (thread_local_top()->external_caught_exception_) { | 1268 } else if (thread_local_top()->external_caught_exception_) { |
1269 // If the exception is externally caught, clear it if there are no | 1269 // If the exception is externally caught, clear it if there are no |
1270 // JavaScript frames on the way to the C++ frame that has the | 1270 // JavaScript frames on the way to the C++ frame that has the |
1271 // external handler. | 1271 // external handler. |
1272 ASSERT(thread_local_top()->try_catch_handler_address() != NULL); | 1272 DCHECK(thread_local_top()->try_catch_handler_address() != NULL); |
1273 Address external_handler_address = | 1273 Address external_handler_address = |
1274 thread_local_top()->try_catch_handler_address(); | 1274 thread_local_top()->try_catch_handler_address(); |
1275 JavaScriptFrameIterator it(this); | 1275 JavaScriptFrameIterator it(this); |
1276 if (it.done() || (it.frame()->sp() > external_handler_address)) { | 1276 if (it.done() || (it.frame()->sp() > external_handler_address)) { |
1277 clear_exception = true; | 1277 clear_exception = true; |
1278 } | 1278 } |
1279 } | 1279 } |
1280 | 1280 |
1281 // Clear the exception if needed. | 1281 // Clear the exception if needed. |
1282 if (clear_exception) { | 1282 if (clear_exception) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 | 1344 |
1345 | 1345 |
1346 char* Isolate::RestoreThread(char* from) { | 1346 char* Isolate::RestoreThread(char* from) { |
1347 MemCopy(reinterpret_cast<char*>(thread_local_top()), from, | 1347 MemCopy(reinterpret_cast<char*>(thread_local_top()), from, |
1348 sizeof(ThreadLocalTop)); | 1348 sizeof(ThreadLocalTop)); |
1349 // This might be just paranoia, but it seems to be needed in case a | 1349 // This might be just paranoia, but it seems to be needed in case a |
1350 // thread_local_top_ is restored on a separate OS thread. | 1350 // thread_local_top_ is restored on a separate OS thread. |
1351 #ifdef USE_SIMULATOR | 1351 #ifdef USE_SIMULATOR |
1352 thread_local_top()->simulator_ = Simulator::current(this); | 1352 thread_local_top()->simulator_ = Simulator::current(this); |
1353 #endif | 1353 #endif |
1354 ASSERT(context() == NULL || context()->IsContext()); | 1354 DCHECK(context() == NULL || context()->IsContext()); |
1355 return from + sizeof(ThreadLocalTop); | 1355 return from + sizeof(ThreadLocalTop); |
1356 } | 1356 } |
1357 | 1357 |
1358 | 1358 |
1359 Isolate::ThreadDataTable::ThreadDataTable() | 1359 Isolate::ThreadDataTable::ThreadDataTable() |
1360 : list_(NULL) { | 1360 : list_(NULL) { |
1361 } | 1361 } |
1362 | 1362 |
1363 | 1363 |
1364 Isolate::ThreadDataTable::~ThreadDataTable() { | 1364 Isolate::ThreadDataTable::~ThreadDataTable() { |
1365 // TODO(svenpanne) The assertion below would fire if an embedder does not | 1365 // TODO(svenpanne) The assertion below would fire if an embedder does not |
1366 // cleanly dispose all Isolates before disposing v8, so we are conservative | 1366 // cleanly dispose all Isolates before disposing v8, so we are conservative |
1367 // and leave it out for now. | 1367 // and leave it out for now. |
1368 // ASSERT_EQ(NULL, list_); | 1368 // DCHECK_EQ(NULL, list_); |
1369 } | 1369 } |
1370 | 1370 |
1371 | 1371 |
1372 Isolate::PerIsolateThreadData::~PerIsolateThreadData() { | 1372 Isolate::PerIsolateThreadData::~PerIsolateThreadData() { |
1373 #if defined(USE_SIMULATOR) | 1373 #if defined(USE_SIMULATOR) |
1374 delete simulator_; | 1374 delete simulator_; |
1375 #endif | 1375 #endif |
1376 } | 1376 } |
1377 | 1377 |
1378 | 1378 |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1636 } | 1636 } |
1637 | 1637 |
1638 | 1638 |
1639 Isolate::~Isolate() { | 1639 Isolate::~Isolate() { |
1640 TRACE_ISOLATE(destructor); | 1640 TRACE_ISOLATE(destructor); |
1641 | 1641 |
1642 // Has to be called while counters_ are still alive | 1642 // Has to be called while counters_ are still alive |
1643 runtime_zone_.DeleteKeptSegment(); | 1643 runtime_zone_.DeleteKeptSegment(); |
1644 | 1644 |
1645 // The entry stack must be empty when we get here. | 1645 // The entry stack must be empty when we get here. |
1646 ASSERT(entry_stack_ == NULL || entry_stack_->previous_item == NULL); | 1646 DCHECK(entry_stack_ == NULL || entry_stack_->previous_item == NULL); |
1647 | 1647 |
1648 delete entry_stack_; | 1648 delete entry_stack_; |
1649 entry_stack_ = NULL; | 1649 entry_stack_ = NULL; |
1650 | 1650 |
1651 delete[] assembler_spare_buffer_; | 1651 delete[] assembler_spare_buffer_; |
1652 assembler_spare_buffer_ = NULL; | 1652 assembler_spare_buffer_ = NULL; |
1653 | 1653 |
1654 delete unicode_cache_; | 1654 delete unicode_cache_; |
1655 unicode_cache_ = NULL; | 1655 unicode_cache_ = NULL; |
1656 | 1656 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1730 } | 1730 } |
1731 | 1731 |
1732 | 1732 |
1733 void Isolate::InitializeThreadLocal() { | 1733 void Isolate::InitializeThreadLocal() { |
1734 thread_local_top_.isolate_ = this; | 1734 thread_local_top_.isolate_ = this; |
1735 thread_local_top_.Initialize(); | 1735 thread_local_top_.Initialize(); |
1736 } | 1736 } |
1737 | 1737 |
1738 | 1738 |
1739 bool Isolate::PropagatePendingExceptionToExternalTryCatch() { | 1739 bool Isolate::PropagatePendingExceptionToExternalTryCatch() { |
1740 ASSERT(has_pending_exception()); | 1740 DCHECK(has_pending_exception()); |
1741 | 1741 |
1742 bool has_external_try_catch = HasExternalTryCatch(); | 1742 bool has_external_try_catch = HasExternalTryCatch(); |
1743 if (!has_external_try_catch) { | 1743 if (!has_external_try_catch) { |
1744 thread_local_top_.external_caught_exception_ = false; | 1744 thread_local_top_.external_caught_exception_ = false; |
1745 return true; | 1745 return true; |
1746 } | 1746 } |
1747 | 1747 |
1748 bool catchable_by_js = is_catchable_by_javascript(pending_exception()); | 1748 bool catchable_by_js = is_catchable_by_javascript(pending_exception()); |
1749 if (catchable_by_js && IsFinallyOnTop()) { | 1749 if (catchable_by_js && IsFinallyOnTop()) { |
1750 thread_local_top_.external_caught_exception_ = false; | 1750 thread_local_top_.external_caught_exception_ = false; |
1751 return false; | 1751 return false; |
1752 } | 1752 } |
1753 | 1753 |
1754 thread_local_top_.external_caught_exception_ = true; | 1754 thread_local_top_.external_caught_exception_ = true; |
1755 if (thread_local_top_.pending_exception_ == heap()->termination_exception()) { | 1755 if (thread_local_top_.pending_exception_ == heap()->termination_exception()) { |
1756 try_catch_handler()->can_continue_ = false; | 1756 try_catch_handler()->can_continue_ = false; |
1757 try_catch_handler()->has_terminated_ = true; | 1757 try_catch_handler()->has_terminated_ = true; |
1758 try_catch_handler()->exception_ = heap()->null_value(); | 1758 try_catch_handler()->exception_ = heap()->null_value(); |
1759 } else { | 1759 } else { |
1760 v8::TryCatch* handler = try_catch_handler(); | 1760 v8::TryCatch* handler = try_catch_handler(); |
1761 ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() || | 1761 DCHECK(thread_local_top_.pending_message_obj_->IsJSMessageObject() || |
1762 thread_local_top_.pending_message_obj_->IsTheHole()); | 1762 thread_local_top_.pending_message_obj_->IsTheHole()); |
1763 ASSERT(thread_local_top_.pending_message_script_->IsScript() || | 1763 DCHECK(thread_local_top_.pending_message_script_->IsScript() || |
1764 thread_local_top_.pending_message_script_->IsTheHole()); | 1764 thread_local_top_.pending_message_script_->IsTheHole()); |
1765 handler->can_continue_ = true; | 1765 handler->can_continue_ = true; |
1766 handler->has_terminated_ = false; | 1766 handler->has_terminated_ = false; |
1767 handler->exception_ = pending_exception(); | 1767 handler->exception_ = pending_exception(); |
1768 // Propagate to the external try-catch only if we got an actual message. | 1768 // Propagate to the external try-catch only if we got an actual message. |
1769 if (thread_local_top_.pending_message_obj_->IsTheHole()) return true; | 1769 if (thread_local_top_.pending_message_obj_->IsTheHole()) return true; |
1770 | 1770 |
1771 handler->message_obj_ = thread_local_top_.pending_message_obj_; | 1771 handler->message_obj_ = thread_local_top_.pending_message_obj_; |
1772 handler->message_script_ = thread_local_top_.pending_message_script_; | 1772 handler->message_script_ = thread_local_top_.pending_message_script_; |
1773 handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_; | 1773 handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_; |
1774 handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_; | 1774 handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_; |
1775 } | 1775 } |
1776 return true; | 1776 return true; |
1777 } | 1777 } |
1778 | 1778 |
1779 | 1779 |
1780 void Isolate::InitializeLoggingAndCounters() { | 1780 void Isolate::InitializeLoggingAndCounters() { |
1781 if (logger_ == NULL) { | 1781 if (logger_ == NULL) { |
1782 logger_ = new Logger(this); | 1782 logger_ = new Logger(this); |
1783 } | 1783 } |
1784 if (counters_ == NULL) { | 1784 if (counters_ == NULL) { |
1785 counters_ = new Counters(this); | 1785 counters_ = new Counters(this); |
1786 } | 1786 } |
1787 } | 1787 } |
1788 | 1788 |
1789 | 1789 |
1790 bool Isolate::Init(Deserializer* des) { | 1790 bool Isolate::Init(Deserializer* des) { |
1791 ASSERT(state_ != INITIALIZED); | 1791 DCHECK(state_ != INITIALIZED); |
1792 TRACE_ISOLATE(init); | 1792 TRACE_ISOLATE(init); |
1793 | 1793 |
1794 stress_deopt_count_ = FLAG_deopt_every_n_times; | 1794 stress_deopt_count_ = FLAG_deopt_every_n_times; |
1795 | 1795 |
1796 has_fatal_error_ = false; | 1796 has_fatal_error_ = false; |
1797 | 1797 |
1798 if (function_entry_hook() != NULL) { | 1798 if (function_entry_hook() != NULL) { |
1799 // When function entry hooking is in effect, we have to create the code | 1799 // When function entry hooking is in effect, we have to create the code |
1800 // stubs from scratch to get entry hooks, rather than loading the previously | 1800 // stubs from scratch to get entry hooks, rather than loading the previously |
1801 // generated stubs from disk. | 1801 // generated stubs from disk. |
1802 // If this assert fires, the initialization path has regressed. | 1802 // If this assert fires, the initialization path has regressed. |
1803 ASSERT(des == NULL); | 1803 DCHECK(des == NULL); |
1804 } | 1804 } |
1805 | 1805 |
1806 // The initialization process does not handle memory exhaustion. | 1806 // The initialization process does not handle memory exhaustion. |
1807 DisallowAllocationFailure disallow_allocation_failure(this); | 1807 DisallowAllocationFailure disallow_allocation_failure(this); |
1808 | 1808 |
1809 memory_allocator_ = new MemoryAllocator(this); | 1809 memory_allocator_ = new MemoryAllocator(this); |
1810 code_range_ = new CodeRange(this); | 1810 code_range_ = new CodeRange(this); |
1811 | 1811 |
1812 // Safe after setting Heap::isolate_, and initializing StackGuard | 1812 // Safe after setting Heap::isolate_, and initializing StackGuard |
1813 heap_.SetStackLimits(); | 1813 heap_.SetStackLimits(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1858 | 1858 |
1859 { // NOLINT | 1859 { // NOLINT |
1860 // Ensure that the thread has a valid stack guard. The v8::Locker object | 1860 // Ensure that the thread has a valid stack guard. The v8::Locker object |
1861 // will ensure this too, but we don't have to use lockers if we are only | 1861 // will ensure this too, but we don't have to use lockers if we are only |
1862 // using one thread. | 1862 // using one thread. |
1863 ExecutionAccess lock(this); | 1863 ExecutionAccess lock(this); |
1864 stack_guard_.InitThread(lock); | 1864 stack_guard_.InitThread(lock); |
1865 } | 1865 } |
1866 | 1866 |
1867 // SetUp the object heap. | 1867 // SetUp the object heap. |
1868 ASSERT(!heap_.HasBeenSetUp()); | 1868 DCHECK(!heap_.HasBeenSetUp()); |
1869 if (!heap_.SetUp()) { | 1869 if (!heap_.SetUp()) { |
1870 V8::FatalProcessOutOfMemory("heap setup"); | 1870 V8::FatalProcessOutOfMemory("heap setup"); |
1871 return false; | 1871 return false; |
1872 } | 1872 } |
1873 | 1873 |
1874 deoptimizer_data_ = new DeoptimizerData(memory_allocator_); | 1874 deoptimizer_data_ = new DeoptimizerData(memory_allocator_); |
1875 | 1875 |
1876 const bool create_heap_objects = (des == NULL); | 1876 const bool create_heap_objects = (des == NULL); |
1877 if (create_heap_objects && !heap_.CreateHeapObjects()) { | 1877 if (create_heap_objects && !heap_.CreateHeapObjects()) { |
1878 V8::FatalProcessOutOfMemory("heap object creation"); | 1878 V8::FatalProcessOutOfMemory("heap object creation"); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2024 } | 2024 } |
2025 return stats_table_; | 2025 return stats_table_; |
2026 } | 2026 } |
2027 | 2027 |
2028 | 2028 |
2029 void Isolate::Enter() { | 2029 void Isolate::Enter() { |
2030 Isolate* current_isolate = NULL; | 2030 Isolate* current_isolate = NULL; |
2031 PerIsolateThreadData* current_data = CurrentPerIsolateThreadData(); | 2031 PerIsolateThreadData* current_data = CurrentPerIsolateThreadData(); |
2032 if (current_data != NULL) { | 2032 if (current_data != NULL) { |
2033 current_isolate = current_data->isolate_; | 2033 current_isolate = current_data->isolate_; |
2034 ASSERT(current_isolate != NULL); | 2034 DCHECK(current_isolate != NULL); |
2035 if (current_isolate == this) { | 2035 if (current_isolate == this) { |
2036 ASSERT(Current() == this); | 2036 DCHECK(Current() == this); |
2037 ASSERT(entry_stack_ != NULL); | 2037 DCHECK(entry_stack_ != NULL); |
2038 ASSERT(entry_stack_->previous_thread_data == NULL || | 2038 DCHECK(entry_stack_->previous_thread_data == NULL || |
2039 entry_stack_->previous_thread_data->thread_id().Equals( | 2039 entry_stack_->previous_thread_data->thread_id().Equals( |
2040 ThreadId::Current())); | 2040 ThreadId::Current())); |
2041 // Same thread re-enters the isolate, no need to re-init anything. | 2041 // Same thread re-enters the isolate, no need to re-init anything. |
2042 entry_stack_->entry_count++; | 2042 entry_stack_->entry_count++; |
2043 return; | 2043 return; |
2044 } | 2044 } |
2045 } | 2045 } |
2046 | 2046 |
2047 PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread(); | 2047 PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread(); |
2048 ASSERT(data != NULL); | 2048 DCHECK(data != NULL); |
2049 ASSERT(data->isolate_ == this); | 2049 DCHECK(data->isolate_ == this); |
2050 | 2050 |
2051 EntryStackItem* item = new EntryStackItem(current_data, | 2051 EntryStackItem* item = new EntryStackItem(current_data, |
2052 current_isolate, | 2052 current_isolate, |
2053 entry_stack_); | 2053 entry_stack_); |
2054 entry_stack_ = item; | 2054 entry_stack_ = item; |
2055 | 2055 |
2056 SetIsolateThreadLocals(this, data); | 2056 SetIsolateThreadLocals(this, data); |
2057 | 2057 |
2058 // In case it's the first time some thread enters the isolate. | 2058 // In case it's the first time some thread enters the isolate. |
2059 set_thread_id(data->thread_id()); | 2059 set_thread_id(data->thread_id()); |
2060 } | 2060 } |
2061 | 2061 |
2062 | 2062 |
2063 void Isolate::Exit() { | 2063 void Isolate::Exit() { |
2064 ASSERT(entry_stack_ != NULL); | 2064 DCHECK(entry_stack_ != NULL); |
2065 ASSERT(entry_stack_->previous_thread_data == NULL || | 2065 DCHECK(entry_stack_->previous_thread_data == NULL || |
2066 entry_stack_->previous_thread_data->thread_id().Equals( | 2066 entry_stack_->previous_thread_data->thread_id().Equals( |
2067 ThreadId::Current())); | 2067 ThreadId::Current())); |
2068 | 2068 |
2069 if (--entry_stack_->entry_count > 0) return; | 2069 if (--entry_stack_->entry_count > 0) return; |
2070 | 2070 |
2071 ASSERT(CurrentPerIsolateThreadData() != NULL); | 2071 DCHECK(CurrentPerIsolateThreadData() != NULL); |
2072 ASSERT(CurrentPerIsolateThreadData()->isolate_ == this); | 2072 DCHECK(CurrentPerIsolateThreadData()->isolate_ == this); |
2073 | 2073 |
2074 // Pop the stack. | 2074 // Pop the stack. |
2075 EntryStackItem* item = entry_stack_; | 2075 EntryStackItem* item = entry_stack_; |
2076 entry_stack_ = item->previous_item; | 2076 entry_stack_ = item->previous_item; |
2077 | 2077 |
2078 PerIsolateThreadData* previous_thread_data = item->previous_thread_data; | 2078 PerIsolateThreadData* previous_thread_data = item->previous_thread_data; |
2079 Isolate* previous_isolate = item->previous_isolate; | 2079 Isolate* previous_isolate = item->previous_isolate; |
2080 | 2080 |
2081 delete item; | 2081 delete item; |
2082 | 2082 |
(...skipping 11 matching lines...) Expand all Loading... |
2094 } | 2094 } |
2095 | 2095 |
2096 | 2096 |
2097 void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) { | 2097 void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) { |
2098 #ifdef DEBUG | 2098 #ifdef DEBUG |
2099 // In debug mode assert that the linked list is well-formed. | 2099 // In debug mode assert that the linked list is well-formed. |
2100 DeferredHandles* deferred_iterator = deferred; | 2100 DeferredHandles* deferred_iterator = deferred; |
2101 while (deferred_iterator->previous_ != NULL) { | 2101 while (deferred_iterator->previous_ != NULL) { |
2102 deferred_iterator = deferred_iterator->previous_; | 2102 deferred_iterator = deferred_iterator->previous_; |
2103 } | 2103 } |
2104 ASSERT(deferred_handles_head_ == deferred_iterator); | 2104 DCHECK(deferred_handles_head_ == deferred_iterator); |
2105 #endif | 2105 #endif |
2106 if (deferred_handles_head_ == deferred) { | 2106 if (deferred_handles_head_ == deferred) { |
2107 deferred_handles_head_ = deferred_handles_head_->next_; | 2107 deferred_handles_head_ = deferred_handles_head_->next_; |
2108 } | 2108 } |
2109 if (deferred->next_ != NULL) { | 2109 if (deferred->next_ != NULL) { |
2110 deferred->next_->previous_ = deferred->previous_; | 2110 deferred->next_->previous_ = deferred->previous_; |
2111 } | 2111 } |
2112 if (deferred->previous_ != NULL) { | 2112 if (deferred->previous_ != NULL) { |
2113 deferred->previous_->next_ = deferred->next_; | 2113 deferred->previous_->next_ = deferred->next_; |
2114 } | 2114 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2156 bool Isolate::use_crankshaft() const { | 2156 bool Isolate::use_crankshaft() const { |
2157 return FLAG_crankshaft && | 2157 return FLAG_crankshaft && |
2158 !serializer_enabled_ && | 2158 !serializer_enabled_ && |
2159 CpuFeatures::SupportsCrankshaft(); | 2159 CpuFeatures::SupportsCrankshaft(); |
2160 } | 2160 } |
2161 | 2161 |
2162 | 2162 |
2163 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() { | 2163 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() { |
2164 Map* root_array_map = | 2164 Map* root_array_map = |
2165 get_initial_js_array_map(GetInitialFastElementsKind()); | 2165 get_initial_js_array_map(GetInitialFastElementsKind()); |
2166 ASSERT(root_array_map != NULL); | 2166 DCHECK(root_array_map != NULL); |
2167 JSObject* initial_array_proto = JSObject::cast(*initial_array_prototype()); | 2167 JSObject* initial_array_proto = JSObject::cast(*initial_array_prototype()); |
2168 | 2168 |
2169 // Check that the array prototype hasn't been altered WRT empty elements. | 2169 // Check that the array prototype hasn't been altered WRT empty elements. |
2170 if (root_array_map->prototype() != initial_array_proto) return false; | 2170 if (root_array_map->prototype() != initial_array_proto) return false; |
2171 if (initial_array_proto->elements() != heap()->empty_fixed_array()) { | 2171 if (initial_array_proto->elements() != heap()->empty_fixed_array()) { |
2172 return false; | 2172 return false; |
2173 } | 2173 } |
2174 | 2174 |
2175 // Check that the object prototype hasn't been altered WRT empty elements. | 2175 // Check that the object prototype hasn't been altered WRT empty elements. |
2176 JSObject* initial_object_proto = JSObject::cast(*initial_object_prototype()); | 2176 JSObject* initial_object_proto = JSObject::cast(*initial_object_prototype()); |
(...skipping 11 matching lines...) Expand all Loading... |
2188 | 2188 |
2189 | 2189 |
2190 CodeStubInterfaceDescriptor* | 2190 CodeStubInterfaceDescriptor* |
2191 Isolate::code_stub_interface_descriptor(int index) { | 2191 Isolate::code_stub_interface_descriptor(int index) { |
2192 return code_stub_interface_descriptors_ + index; | 2192 return code_stub_interface_descriptors_ + index; |
2193 } | 2193 } |
2194 | 2194 |
2195 | 2195 |
2196 CallInterfaceDescriptor* | 2196 CallInterfaceDescriptor* |
2197 Isolate::call_descriptor(CallDescriptorKey index) { | 2197 Isolate::call_descriptor(CallDescriptorKey index) { |
2198 ASSERT(0 <= index && index < NUMBER_OF_CALL_DESCRIPTORS); | 2198 DCHECK(0 <= index && index < NUMBER_OF_CALL_DESCRIPTORS); |
2199 return &call_descriptors_[index]; | 2199 return &call_descriptors_[index]; |
2200 } | 2200 } |
2201 | 2201 |
2202 | 2202 |
2203 Object* Isolate::FindCodeObject(Address a) { | 2203 Object* Isolate::FindCodeObject(Address a) { |
2204 return inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer(a); | 2204 return inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer(a); |
2205 } | 2205 } |
2206 | 2206 |
2207 | 2207 |
2208 #ifdef DEBUG | 2208 #ifdef DEBUG |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2261 // Fire callbacks. Increase call depth to prevent recursive callbacks. | 2261 // Fire callbacks. Increase call depth to prevent recursive callbacks. |
2262 v8::Isolate::SuppressMicrotaskExecutionScope suppress( | 2262 v8::Isolate::SuppressMicrotaskExecutionScope suppress( |
2263 reinterpret_cast<v8::Isolate*>(this)); | 2263 reinterpret_cast<v8::Isolate*>(this)); |
2264 for (int i = 0; i < call_completed_callbacks_.length(); i++) { | 2264 for (int i = 0; i < call_completed_callbacks_.length(); i++) { |
2265 call_completed_callbacks_.at(i)(); | 2265 call_completed_callbacks_.at(i)(); |
2266 } | 2266 } |
2267 } | 2267 } |
2268 | 2268 |
2269 | 2269 |
2270 void Isolate::EnqueueMicrotask(Handle<Object> microtask) { | 2270 void Isolate::EnqueueMicrotask(Handle<Object> microtask) { |
2271 ASSERT(microtask->IsJSFunction() || microtask->IsCallHandlerInfo()); | 2271 DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo()); |
2272 Handle<FixedArray> queue(heap()->microtask_queue(), this); | 2272 Handle<FixedArray> queue(heap()->microtask_queue(), this); |
2273 int num_tasks = pending_microtask_count(); | 2273 int num_tasks = pending_microtask_count(); |
2274 ASSERT(num_tasks <= queue->length()); | 2274 DCHECK(num_tasks <= queue->length()); |
2275 if (num_tasks == 0) { | 2275 if (num_tasks == 0) { |
2276 queue = factory()->NewFixedArray(8); | 2276 queue = factory()->NewFixedArray(8); |
2277 heap()->set_microtask_queue(*queue); | 2277 heap()->set_microtask_queue(*queue); |
2278 } else if (num_tasks == queue->length()) { | 2278 } else if (num_tasks == queue->length()) { |
2279 queue = FixedArray::CopySize(queue, num_tasks * 2); | 2279 queue = FixedArray::CopySize(queue, num_tasks * 2); |
2280 heap()->set_microtask_queue(*queue); | 2280 heap()->set_microtask_queue(*queue); |
2281 } | 2281 } |
2282 ASSERT(queue->get(num_tasks)->IsUndefined()); | 2282 DCHECK(queue->get(num_tasks)->IsUndefined()); |
2283 queue->set(num_tasks, *microtask); | 2283 queue->set(num_tasks, *microtask); |
2284 set_pending_microtask_count(num_tasks + 1); | 2284 set_pending_microtask_count(num_tasks + 1); |
2285 } | 2285 } |
2286 | 2286 |
2287 | 2287 |
2288 void Isolate::RunMicrotasks() { | 2288 void Isolate::RunMicrotasks() { |
2289 // %RunMicrotasks may be called in mjsunit tests, which violates | 2289 // %RunMicrotasks may be called in mjsunit tests, which violates |
2290 // this assertion, hence the check for --allow-natives-syntax. | 2290 // this assertion, hence the check for --allow-natives-syntax. |
2291 // TODO(adamk): However, this also fails some layout tests. | 2291 // TODO(adamk): However, this also fails some layout tests. |
2292 // | 2292 // |
2293 // ASSERT(FLAG_allow_natives_syntax || | 2293 // DCHECK(FLAG_allow_natives_syntax || |
2294 // handle_scope_implementer()->CallDepthIsZero()); | 2294 // handle_scope_implementer()->CallDepthIsZero()); |
2295 | 2295 |
2296 // Increase call depth to prevent recursive callbacks. | 2296 // Increase call depth to prevent recursive callbacks. |
2297 v8::Isolate::SuppressMicrotaskExecutionScope suppress( | 2297 v8::Isolate::SuppressMicrotaskExecutionScope suppress( |
2298 reinterpret_cast<v8::Isolate*>(this)); | 2298 reinterpret_cast<v8::Isolate*>(this)); |
2299 | 2299 |
2300 while (pending_microtask_count() > 0) { | 2300 while (pending_microtask_count() > 0) { |
2301 HandleScope scope(this); | 2301 HandleScope scope(this); |
2302 int num_tasks = pending_microtask_count(); | 2302 int num_tasks = pending_microtask_count(); |
2303 Handle<FixedArray> queue(heap()->microtask_queue(), this); | 2303 Handle<FixedArray> queue(heap()->microtask_queue(), this); |
2304 ASSERT(num_tasks <= queue->length()); | 2304 DCHECK(num_tasks <= queue->length()); |
2305 set_pending_microtask_count(0); | 2305 set_pending_microtask_count(0); |
2306 heap()->set_microtask_queue(heap()->empty_fixed_array()); | 2306 heap()->set_microtask_queue(heap()->empty_fixed_array()); |
2307 | 2307 |
2308 for (int i = 0; i < num_tasks; i++) { | 2308 for (int i = 0; i < num_tasks; i++) { |
2309 HandleScope scope(this); | 2309 HandleScope scope(this); |
2310 Handle<Object> microtask(queue->get(i), this); | 2310 Handle<Object> microtask(queue->get(i), this); |
2311 if (microtask->IsJSFunction()) { | 2311 if (microtask->IsJSFunction()) { |
2312 Handle<JSFunction> microtask_function = | 2312 Handle<JSFunction> microtask_function = |
2313 Handle<JSFunction>::cast(microtask); | 2313 Handle<JSFunction>::cast(microtask); |
2314 SaveContext save(this); | 2314 SaveContext save(this); |
(...skipping 18 matching lines...) Expand all Loading... |
2333 v8::ToCData<v8::MicrotaskCallback>(callback_info->callback()); | 2333 v8::ToCData<v8::MicrotaskCallback>(callback_info->callback()); |
2334 void* data = v8::ToCData<void*>(callback_info->data()); | 2334 void* data = v8::ToCData<void*>(callback_info->data()); |
2335 callback(data); | 2335 callback(data); |
2336 } | 2336 } |
2337 } | 2337 } |
2338 } | 2338 } |
2339 } | 2339 } |
2340 | 2340 |
2341 | 2341 |
2342 void Isolate::SetUseCounterCallback(v8::Isolate::UseCounterCallback callback) { | 2342 void Isolate::SetUseCounterCallback(v8::Isolate::UseCounterCallback callback) { |
2343 ASSERT(!use_counter_callback_); | 2343 DCHECK(!use_counter_callback_); |
2344 use_counter_callback_ = callback; | 2344 use_counter_callback_ = callback; |
2345 } | 2345 } |
2346 | 2346 |
2347 | 2347 |
2348 void Isolate::CountUsage(v8::Isolate::UseCounterFeature feature) { | 2348 void Isolate::CountUsage(v8::Isolate::UseCounterFeature feature) { |
2349 if (use_counter_callback_) { | 2349 if (use_counter_callback_) { |
2350 use_counter_callback_(reinterpret_cast<v8::Isolate*>(this), feature); | 2350 use_counter_callback_(reinterpret_cast<v8::Isolate*>(this), feature); |
2351 } | 2351 } |
2352 } | 2352 } |
2353 | 2353 |
(...skipping 15 matching lines...) Expand all Loading... |
2369 if (prev_ && prev_->Intercept(flag)) return true; | 2369 if (prev_ && prev_->Intercept(flag)) return true; |
2370 // Then check whether this scope intercepts. | 2370 // Then check whether this scope intercepts. |
2371 if ((flag & intercept_mask_)) { | 2371 if ((flag & intercept_mask_)) { |
2372 intercepted_flags_ |= flag; | 2372 intercepted_flags_ |= flag; |
2373 return true; | 2373 return true; |
2374 } | 2374 } |
2375 return false; | 2375 return false; |
2376 } | 2376 } |
2377 | 2377 |
2378 } } // namespace v8::internal | 2378 } } // namespace v8::internal |
OLD | NEW |