~james-page/ubuntu/precise/nodejs/test-timeout

« back to all changes in this revision

Viewing changes to deps/v8/src/top.cc

  • Committer: Bazaar Package Importer
  • Author(s): Fabrice Coutadeur
  • Date: 2011-06-30 07:03:44 UTC
  • mfrom: (7.1.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110630070344-5928xvhb3ddw5adb
Tags: 0.4.9-1ubuntu1
* Merge from Debian unstable (LP: #786428). Remaining changes:
  - debian/patches/2007_remove_internet_test.patch: Remove test which requires
    internet connection

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2006-2008 the V8 project authors. All rights reserved.
 
1
// Copyright 2011 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
35
35
#include "platform.h"
36
36
#include "simulator.h"
37
37
#include "string-stream.h"
 
38
#include "vm-state-inl.h"
38
39
 
39
40
namespace v8 {
40
41
namespace internal {
41
42
 
 
43
#ifdef ENABLE_LOGGING_AND_PROFILING
 
44
Semaphore* Top::runtime_profiler_semaphore_ = NULL;
 
45
#endif
42
46
ThreadLocalTop Top::thread_local_;
43
47
Mutex* Top::break_access_ = OS::CreateMutex();
44
48
 
66
70
void ThreadLocalTop::Initialize() {
67
71
  c_entry_fp_ = 0;
68
72
  handler_ = 0;
 
73
#ifdef USE_SIMULATOR
 
74
#ifdef V8_TARGET_ARCH_ARM
 
75
  simulator_ = Simulator::current();
 
76
#elif V8_TARGET_ARCH_MIPS
 
77
  simulator_ = assembler::mips::Simulator::current();
 
78
#endif
 
79
#endif
69
80
#ifdef ENABLE_LOGGING_AND_PROFILING
70
 
  js_entry_sp_ = 0;
71
 
#endif
72
 
  stack_is_cooked_ = false;
 
81
  js_entry_sp_ = NULL;
 
82
  external_callback_ = NULL;
 
83
#endif
 
84
#ifdef ENABLE_VMSTATE_TRACKING
 
85
  current_vm_state_ = EXTERNAL;
 
86
  runtime_profiler_state_ = Top::PROF_NOT_IN_JS;
 
87
#endif
73
88
  try_catch_handler_address_ = NULL;
74
89
  context_ = NULL;
75
90
  int id = ThreadManager::CurrentId();
105
120
 
106
121
 
107
122
void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
108
 
  v->VisitPointer(&(thread->pending_exception_));
 
123
  // Visit the roots from the top for a given thread.
 
124
  Object *pending;
 
125
  // The pending exception can sometimes be a failure.  We can't show
 
126
  // that to the GC, which only understands objects.
 
127
  if (thread->pending_exception_->ToObject(&pending)) {
 
128
    v->VisitPointer(&pending);
 
129
    thread->pending_exception_ = pending;  // In case GC updated it.
 
130
  }
109
131
  v->VisitPointer(&(thread->pending_message_obj_));
110
132
  v->VisitPointer(BitCast<Object**>(&(thread->pending_message_script_)));
111
133
  v->VisitPointer(BitCast<Object**>(&(thread->context_)));
112
 
  v->VisitPointer(&(thread->scheduled_exception_));
 
134
  Object* scheduled;
 
135
  if (thread->scheduled_exception_->ToObject(&scheduled)) {
 
136
    v->VisitPointer(&scheduled);
 
137
    thread->scheduled_exception_ = scheduled;
 
138
  }
113
139
 
114
140
  for (v8::TryCatch* block = thread->TryCatchHandler();
115
141
       block != NULL;
144
170
// into for use by a stacks only core dump (aka minidump).
145
171
class PreallocatedMemoryThread: public Thread {
146
172
 public:
147
 
  PreallocatedMemoryThread() : keep_running_(true) {
 
173
  PreallocatedMemoryThread()
 
174
    : Thread("v8:PreallocMem"),
 
175
      keep_running_(true) {
148
176
    wait_for_ever_semaphore_ = OS::CreateSemaphore(0);
149
177
    data_ready_semaphore_ = OS::CreateSemaphore(0);
150
178
  }
253
281
void Top::Initialize() {
254
282
  CHECK(!initialized);
255
283
 
 
284
#ifdef ENABLE_LOGGING_AND_PROFILING
 
285
  ASSERT(runtime_profiler_semaphore_ == NULL);
 
286
  runtime_profiler_semaphore_ = OS::CreateSemaphore(0);
 
287
#endif
 
288
 
256
289
  InitializeThreadLocal();
257
290
 
258
291
  // Only preallocate on the first initialization.
270
303
 
271
304
void Top::TearDown() {
272
305
  if (initialized) {
 
306
#ifdef ENABLE_LOGGING_AND_PROFILING
 
307
    delete runtime_profiler_semaphore_;
 
308
    runtime_profiler_semaphore_ = NULL;
 
309
#endif
 
310
 
273
311
    // Remove the external reference to the preallocated stack memory.
274
312
    if (preallocated_message_space != NULL) {
275
313
      delete preallocated_message_space;
295
333
 
296
334
 
297
335
void Top::UnregisterTryCatchHandler(v8::TryCatch* that) {
298
 
  ASSERT(thread_local_.TryCatchHandler() == that);
 
336
  ASSERT(try_catch_handler() == that);
299
337
  thread_local_.set_try_catch_handler_address(
300
338
      reinterpret_cast<Address>(that->next_));
301
339
  thread_local_.catcher_ = NULL;
303
341
}
304
342
 
305
343
 
306
 
void Top::MarkCompactPrologue(bool is_compacting) {
307
 
  MarkCompactPrologue(is_compacting, &thread_local_);
308
 
}
309
 
 
310
 
 
311
 
void Top::MarkCompactPrologue(bool is_compacting, char* data) {
312
 
  MarkCompactPrologue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
313
 
}
314
 
 
315
 
 
316
 
void Top::MarkCompactPrologue(bool is_compacting, ThreadLocalTop* thread) {
317
 
  if (is_compacting) {
318
 
    StackFrame::CookFramesForThread(thread);
319
 
  }
320
 
}
321
 
 
322
 
 
323
 
void Top::MarkCompactEpilogue(bool is_compacting, char* data) {
324
 
  MarkCompactEpilogue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
325
 
}
326
 
 
327
 
 
328
 
void Top::MarkCompactEpilogue(bool is_compacting) {
329
 
  MarkCompactEpilogue(is_compacting, &thread_local_);
330
 
}
331
 
 
332
 
 
333
 
void Top::MarkCompactEpilogue(bool is_compacting, ThreadLocalTop* thread) {
334
 
  if (is_compacting) {
335
 
    StackFrame::UncookFramesForThread(thread);
336
 
  }
337
 
}
338
 
 
339
344
 
340
345
static int stack_trace_nesting_level = 0;
341
346
static StringStream* incomplete_message = NULL;
375
380
  int limit = Max(frame_limit, 0);
376
381
  Handle<JSArray> stack_trace = Factory::NewJSArray(frame_limit);
377
382
 
378
 
  Handle<String> column_key =  Factory::LookupAsciiSymbol("column");
379
 
  Handle<String> line_key =  Factory::LookupAsciiSymbol("lineNumber");
380
 
  Handle<String> script_key =  Factory::LookupAsciiSymbol("scriptName");
381
 
  Handle<String> function_key =  Factory::LookupAsciiSymbol("functionName");
382
 
  Handle<String> eval_key =  Factory::LookupAsciiSymbol("isEval");
383
 
  Handle<String> constructor_key =  Factory::LookupAsciiSymbol("isConstructor");
 
383
  Handle<String> column_key = Factory::LookupAsciiSymbol("column");
 
384
  Handle<String> line_key = Factory::LookupAsciiSymbol("lineNumber");
 
385
  Handle<String> script_key = Factory::LookupAsciiSymbol("scriptName");
 
386
  Handle<String> name_or_source_url_key =
 
387
      Factory::LookupAsciiSymbol("nameOrSourceURL");
 
388
  Handle<String> script_name_or_source_url_key =
 
389
      Factory::LookupAsciiSymbol("scriptNameOrSourceURL");
 
390
  Handle<String> function_key = Factory::LookupAsciiSymbol("functionName");
 
391
  Handle<String> eval_key = Factory::LookupAsciiSymbol("isEval");
 
392
  Handle<String> constructor_key = Factory::LookupAsciiSymbol("isConstructor");
384
393
 
385
394
  StackTraceFrameIterator it;
386
395
  int frames_seen = 0;
387
396
  while (!it.done() && (frames_seen < limit)) {
388
 
    // Create a JSObject to hold the information for the StackFrame.
389
 
    Handle<JSObject> stackFrame = Factory::NewJSObject(object_function());
390
 
 
391
397
    JavaScriptFrame* frame = it.frame();
392
 
    JSFunction* fun(JSFunction::cast(frame->function()));
393
 
    Script* script = Script::cast(fun->shared()->script());
394
 
 
395
 
    if (options & StackTrace::kLineNumber) {
396
 
      int script_line_offset = script->line_offset()->value();
397
 
      int position = frame->code()->SourcePosition(frame->pc());
398
 
      int line_number = GetScriptLineNumber(Handle<Script>(script), position);
399
 
      // line_number is already shifted by the script_line_offset.
400
 
      int relative_line_number = line_number - script_line_offset;
401
 
      if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
402
 
        Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
403
 
        int start = (relative_line_number == 0) ? 0 :
404
 
            Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
405
 
        int column_offset = position - start;
406
 
        if (relative_line_number == 0) {
407
 
          // For the case where the code is on the same line as the script tag.
408
 
          column_offset += script->column_offset()->value();
409
 
        }
410
 
        SetProperty(stackFrame, column_key,
411
 
                    Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE);
412
 
      }
413
 
      SetProperty(stackFrame, line_key,
414
 
                  Handle<Smi>(Smi::FromInt(line_number + 1)), NONE);
415
 
    }
416
 
 
417
 
    if (options & StackTrace::kScriptName) {
418
 
      Handle<Object> script_name(script->name());
419
 
      SetProperty(stackFrame, script_key, script_name, NONE);
420
 
    }
421
 
 
422
 
    if (options & StackTrace::kFunctionName) {
423
 
      Handle<Object> fun_name(fun->shared()->name());
424
 
      if (fun_name->ToBoolean()->IsFalse()) {
425
 
        fun_name = Handle<Object>(fun->shared()->inferred_name());
426
 
      }
427
 
      SetProperty(stackFrame, function_key, fun_name, NONE);
428
 
    }
429
 
 
430
 
    if (options & StackTrace::kIsEval) {
431
 
      int type = Smi::cast(script->compilation_type())->value();
432
 
      Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
433
 
          Factory::true_value() : Factory::false_value();
434
 
      SetProperty(stackFrame, eval_key, is_eval, NONE);
435
 
    }
436
 
 
437
 
    if (options & StackTrace::kIsConstructor) {
438
 
      Handle<Object> is_constructor = (frame->IsConstructor()) ?
439
 
          Factory::true_value() : Factory::false_value();
440
 
      SetProperty(stackFrame, constructor_key, is_constructor, NONE);
441
 
    }
442
 
 
443
 
    FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame);
444
 
    frames_seen++;
 
398
 
 
399
    List<FrameSummary> frames(3);  // Max 2 levels of inlining.
 
400
    frame->Summarize(&frames);
 
401
    for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
 
402
      // Create a JSObject to hold the information for the StackFrame.
 
403
      Handle<JSObject> stackFrame = Factory::NewJSObject(object_function());
 
404
 
 
405
      Handle<JSFunction> fun = frames[i].function();
 
406
      Handle<Script> script(Script::cast(fun->shared()->script()));
 
407
 
 
408
      if (options & StackTrace::kLineNumber) {
 
409
        int script_line_offset = script->line_offset()->value();
 
410
        int position = frames[i].code()->SourcePosition(frames[i].pc());
 
411
        int line_number = GetScriptLineNumber(script, position);
 
412
        // line_number is already shifted by the script_line_offset.
 
413
        int relative_line_number = line_number - script_line_offset;
 
414
        if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
 
415
          Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
 
416
          int start = (relative_line_number == 0) ? 0 :
 
417
              Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
 
418
          int column_offset = position - start;
 
419
          if (relative_line_number == 0) {
 
420
            // For the case where the code is on the same line as the script
 
421
            // tag.
 
422
            column_offset += script->column_offset()->value();
 
423
          }
 
424
          SetLocalPropertyNoThrow(stackFrame, column_key,
 
425
                                  Handle<Smi>(Smi::FromInt(column_offset + 1)));
 
426
        }
 
427
        SetLocalPropertyNoThrow(stackFrame, line_key,
 
428
                                Handle<Smi>(Smi::FromInt(line_number + 1)));
 
429
      }
 
430
 
 
431
      if (options & StackTrace::kScriptName) {
 
432
        Handle<Object> script_name(script->name());
 
433
        SetLocalPropertyNoThrow(stackFrame, script_key, script_name);
 
434
      }
 
435
 
 
436
      if (options & StackTrace::kScriptNameOrSourceURL) {
 
437
        Handle<Object> script_name(script->name());
 
438
        Handle<JSValue> script_wrapper = GetScriptWrapper(script);
 
439
        Handle<Object> property = GetProperty(script_wrapper,
 
440
                                              name_or_source_url_key);
 
441
        ASSERT(property->IsJSFunction());
 
442
        Handle<JSFunction> method = Handle<JSFunction>::cast(property);
 
443
        bool caught_exception;
 
444
        Handle<Object> result = Execution::TryCall(method, script_wrapper, 0,
 
445
                                                   NULL, &caught_exception);
 
446
        if (caught_exception) {
 
447
          result = Factory::undefined_value();
 
448
        }
 
449
        SetLocalPropertyNoThrow(stackFrame, script_name_or_source_url_key,
 
450
                                result);
 
451
      }
 
452
 
 
453
      if (options & StackTrace::kFunctionName) {
 
454
        Handle<Object> fun_name(fun->shared()->name());
 
455
        if (fun_name->ToBoolean()->IsFalse()) {
 
456
          fun_name = Handle<Object>(fun->shared()->inferred_name());
 
457
        }
 
458
        SetLocalPropertyNoThrow(stackFrame, function_key, fun_name);
 
459
      }
 
460
 
 
461
      if (options & StackTrace::kIsEval) {
 
462
        int type = Smi::cast(script->compilation_type())->value();
 
463
        Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
 
464
            Factory::true_value() : Factory::false_value();
 
465
        SetLocalPropertyNoThrow(stackFrame, eval_key, is_eval);
 
466
      }
 
467
 
 
468
      if (options & StackTrace::kIsConstructor) {
 
469
        Handle<Object> is_constructor = (frames[i].is_constructor()) ?
 
470
            Factory::true_value() : Factory::false_value();
 
471
        SetLocalPropertyNoThrow(stackFrame, constructor_key, is_constructor);
 
472
      }
 
473
 
 
474
      FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame);
 
475
      frames_seen++;
 
476
    }
445
477
    it.Advance();
446
478
  }
447
479
 
699
731
}
700
732
 
701
733
 
702
 
Failure* Top::ReThrow(Object* exception, MessageLocation* location) {
 
734
Failure* Top::ReThrow(MaybeObject* exception, MessageLocation* location) {
 
735
  bool can_be_caught_externally = false;
 
736
  ShouldReportException(&can_be_caught_externally,
 
737
                        is_catchable_by_javascript(exception));
 
738
  thread_local_.catcher_ = can_be_caught_externally ?
 
739
      try_catch_handler() : NULL;
 
740
 
703
741
  // Set the exception being re-thrown.
704
742
  set_pending_exception(exception);
 
743
  if (exception->IsFailure()) return exception->ToFailureUnchecked();
705
744
  return Failure::Exception();
706
745
}
707
746
 
721
760
}
722
761
 
723
762
 
724
 
Object* Top::PromoteScheduledException() {
725
 
  Object* thrown = scheduled_exception();
 
763
Failure* Top::PromoteScheduledException() {
 
764
  MaybeObject* thrown = scheduled_exception();
726
765
  clear_scheduled_exception();
727
766
  // Re-throw the exception to avoid getting repeated error reporting.
728
767
  return ReThrow(thrown);
775
814
}
776
815
 
777
816
 
778
 
bool Top::ShouldReturnException(bool* is_caught_externally,
 
817
bool Top::ShouldReportException(bool* can_be_caught_externally,
779
818
                                bool catchable_by_javascript) {
780
819
  // Find the top-most try-catch handler.
781
820
  StackHandler* handler =
791
830
  // The exception has been externally caught if and only if there is
792
831
  // an external handler which is on top of the top-most try-catch
793
832
  // handler.
794
 
  *is_caught_externally = external_handler_address != NULL &&
 
833
  *can_be_caught_externally = external_handler_address != NULL &&
795
834
      (handler == NULL || handler->address() > external_handler_address ||
796
835
       !catchable_by_javascript);
797
836
 
798
 
  if (*is_caught_externally) {
 
837
  if (*can_be_caught_externally) {
799
838
    // Only report the exception if the external handler is verbose.
800
 
    return thread_local_.TryCatchHandler()->is_verbose_;
 
839
    return try_catch_handler()->is_verbose_;
801
840
  } else {
802
841
    // Report the exception if it isn't caught by JavaScript code.
803
842
    return handler == NULL;
805
844
}
806
845
 
807
846
 
808
 
void Top::DoThrow(Object* exception,
 
847
void Top::DoThrow(MaybeObject* exception,
809
848
                  MessageLocation* location,
810
849
                  const char* message) {
811
850
  ASSERT(!has_pending_exception());
812
851
 
813
852
  HandleScope scope;
814
 
  Handle<Object> exception_handle(exception);
 
853
  Object* exception_object = Smi::FromInt(0);
 
854
  bool is_object = exception->ToObject(&exception_object);
 
855
  Handle<Object> exception_handle(exception_object);
815
856
 
816
857
  // Determine reporting and whether the exception is caught externally.
817
 
  bool is_caught_externally = false;
818
 
  bool is_out_of_memory = exception == Failure::OutOfMemoryException();
819
 
  bool is_termination_exception = exception == Heap::termination_exception();
820
 
  bool catchable_by_javascript = !is_termination_exception && !is_out_of_memory;
821
 
  bool should_return_exception =
822
 
      ShouldReturnException(&is_caught_externally, catchable_by_javascript);
823
 
  bool report_exception = catchable_by_javascript && should_return_exception;
 
858
  bool catchable_by_javascript = is_catchable_by_javascript(exception);
 
859
  // Only real objects can be caught by JS.
 
860
  ASSERT(!catchable_by_javascript || is_object);
 
861
  bool can_be_caught_externally = false;
 
862
  bool should_report_exception =
 
863
      ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
 
864
  bool report_exception = catchable_by_javascript && should_report_exception;
824
865
 
825
866
#ifdef ENABLE_DEBUGGER_SUPPORT
826
867
  // Notify debugger of exception.
833
874
  Handle<Object> message_obj;
834
875
  MessageLocation potential_computed_location;
835
876
  bool try_catch_needs_message =
836
 
      is_caught_externally &&
837
 
      thread_local_.TryCatchHandler()->capture_message_;
 
877
      can_be_caught_externally &&
 
878
      try_catch_handler()->capture_message_;
838
879
  if (report_exception || try_catch_needs_message) {
839
880
    if (location == NULL) {
840
881
      // If no location was specified we use a computed one instead
853
894
              stack_trace_for_uncaught_exceptions_frame_limit,
854
895
              stack_trace_for_uncaught_exceptions_options);
855
896
      }
 
897
      ASSERT(is_object);  // Can't use the handle unless there's a real object.
856
898
      message_obj = MessageHandler::MakeMessageObject("uncaught_exception",
857
899
          location, HandleVector<Object>(&exception_handle, 1), stack_trace,
858
900
          stack_trace_object);
871
913
    }
872
914
  }
873
915
 
874
 
  if (is_caught_externally) {
875
 
    thread_local_.catcher_ = thread_local_.TryCatchHandler();
876
 
  }
 
916
  // Do not forget to clean catcher_ if currently thrown exception cannot
 
917
  // be caught.  If necessary, ReThrow will update the catcher.
 
918
  thread_local_.catcher_ = can_be_caught_externally ?
 
919
      try_catch_handler() : NULL;
877
920
 
878
921
  // NOTE: Notifying the debugger or generating the message
879
922
  // may have caused new exceptions. For now, we just ignore
880
923
  // that and set the pending exception to the original one.
881
 
  set_pending_exception(*exception_handle);
 
924
  if (is_object) {
 
925
    set_pending_exception(*exception_handle);
 
926
  } else {
 
927
    // Failures are not on the heap so they neither need nor work with handles.
 
928
    ASSERT(exception_handle->IsFailure());
 
929
    set_pending_exception(exception);
 
930
  }
 
931
}
 
932
 
 
933
 
 
934
bool Top::IsExternallyCaught() {
 
935
  ASSERT(has_pending_exception());
 
936
 
 
937
  if ((thread_local_.catcher_ == NULL) ||
 
938
      (try_catch_handler() != thread_local_.catcher_)) {
 
939
    // When throwing the exception, we found no v8::TryCatch
 
940
    // which should care about this exception.
 
941
    return false;
 
942
  }
 
943
 
 
944
  if (!is_catchable_by_javascript(pending_exception())) {
 
945
    return true;
 
946
  }
 
947
 
 
948
  // Get the address of the external handler so we can compare the address to
 
949
  // determine which one is closer to the top of the stack.
 
950
  Address external_handler_address = thread_local_.try_catch_handler_address();
 
951
  ASSERT(external_handler_address != NULL);
 
952
 
 
953
  // The exception has been externally caught if and only if there is
 
954
  // an external handler which is on top of the top-most try-finally
 
955
  // handler.
 
956
  // There should be no try-catch blocks as they would prohibit us from
 
957
  // finding external catcher in the first place (see catcher_ check above).
 
958
  //
 
959
  // Note, that finally clause would rethrow an exception unless it's
 
960
  // aborted by jumps in control flow like return, break, etc. and we'll
 
961
  // have another chances to set proper v8::TryCatch.
 
962
  StackHandler* handler =
 
963
      StackHandler::FromAddress(Top::handler(Top::GetCurrentThread()));
 
964
  while (handler != NULL && handler->address() < external_handler_address) {
 
965
    ASSERT(!handler->is_try_catch());
 
966
    if (handler->is_try_finally()) return false;
 
967
 
 
968
    handler = handler->next();
 
969
  }
 
970
 
 
971
  return true;
882
972
}
883
973
 
884
974
 
885
975
void Top::ReportPendingMessages() {
886
976
  ASSERT(has_pending_exception());
887
 
  setup_external_caught();
888
977
  // If the pending exception is OutOfMemoryException set out_of_memory in
889
978
  // the global context.  Note: We have to mark the global context here
890
979
  // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
891
980
  // set it.
892
 
  bool external_caught = thread_local_.external_caught_exception_;
 
981
  bool external_caught = IsExternallyCaught();
 
982
  thread_local_.external_caught_exception_ = external_caught;
893
983
  HandleScope scope;
894
984
  if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) {
895
985
    context()->mark_out_of_memory();
896
986
  } else if (thread_local_.pending_exception_ ==
897
987
             Heap::termination_exception()) {
898
988
    if (external_caught) {
899
 
      thread_local_.TryCatchHandler()->can_continue_ = false;
900
 
      thread_local_.TryCatchHandler()->exception_ = Heap::null_value();
 
989
      try_catch_handler()->can_continue_ = false;
 
990
      try_catch_handler()->exception_ = Heap::null_value();
901
991
    }
902
992
  } else {
903
 
    Handle<Object> exception(pending_exception());
 
993
    // At this point all non-object (failure) exceptions have
 
994
    // been dealt with so this shouldn't fail.
 
995
    Object* pending_exception_object = pending_exception()->ToObjectUnchecked();
 
996
    Handle<Object> exception(pending_exception_object);
904
997
    thread_local_.external_caught_exception_ = false;
905
998
    if (external_caught) {
906
 
      thread_local_.TryCatchHandler()->can_continue_ = true;
907
 
      thread_local_.TryCatchHandler()->exception_ =
908
 
        thread_local_.pending_exception_;
 
999
      try_catch_handler()->can_continue_ = true;
 
1000
      try_catch_handler()->exception_ = thread_local_.pending_exception_;
909
1001
      if (!thread_local_.pending_message_obj_->IsTheHole()) {
910
1002
        try_catch_handler()->message_ = thread_local_.pending_message_obj_;
911
1003
      }
994
1086
 
995
1087
bool Top::is_out_of_memory() {
996
1088
  if (has_pending_exception()) {
997
 
    Object* e = pending_exception();
 
1089
    MaybeObject* e = pending_exception();
998
1090
    if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
999
1091
      return true;
1000
1092
    }
1001
1093
  }
1002
1094
  if (has_scheduled_exception()) {
1003
 
    Object* e = scheduled_exception();
 
1095
    MaybeObject* e = scheduled_exception();
1004
1096
    if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1005
1097
      return true;
1006
1098
    }
1046
1138
 
1047
1139
char* Top::RestoreThread(char* from) {
1048
1140
  memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(thread_local_));
 
1141
  // This might be just paranoia, but it seems to be needed in case a
 
1142
  // thread_local_ is restored on a separate OS thread.
 
1143
#ifdef USE_SIMULATOR
 
1144
#ifdef V8_TARGET_ARCH_ARM
 
1145
  thread_local_.simulator_ = Simulator::current();
 
1146
#elif V8_TARGET_ARCH_MIPS
 
1147
  thread_local_.simulator_ = assembler::mips::Simulator::current();
 
1148
#endif
 
1149
#endif
1049
1150
  return from + sizeof(thread_local_);
1050
1151
}
1051
1152
 
1052
 
 
1053
 
ExecutionAccess::ExecutionAccess() {
1054
 
  Top::break_access_->Lock();
1055
 
}
1056
 
 
1057
 
 
1058
 
ExecutionAccess::~ExecutionAccess() {
1059
 
  Top::break_access_->Unlock();
1060
 
}
1061
 
 
1062
 
 
1063
1153
} }  // namespace v8::internal