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

Side by Side Diff: src/top.cc

Issue 2866008: [Isolates] Move contents of Top into Isolate.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: ensure we're synced Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/top.h ('k') | src/v8.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 21 matching lines...) Expand all
32 #include "debug.h" 32 #include "debug.h"
33 #include "execution.h" 33 #include "execution.h"
34 #include "messages.h" 34 #include "messages.h"
35 #include "platform.h" 35 #include "platform.h"
36 #include "simulator.h" 36 #include "simulator.h"
37 #include "string-stream.h" 37 #include "string-stream.h"
38 38
39 namespace v8 { 39 namespace v8 {
40 namespace internal { 40 namespace internal {
41 41
42 class PreallocatedMemoryThread;
43
44 class TopState {
45 public:
46 TopState()
47 : preallocated_message_space_(NULL),
48 initialized_(false),
49 stack_trace_nesting_level_(0),
50 incomplete_message_(NULL),
51 preallocated_memory_thread_(NULL) {
52 #define C(name) top_addresses_[Top::k_##name] = \
53 reinterpret_cast<Address>(Top::name());
54 TOP_ADDRESS_LIST(C)
55 TOP_ADDRESS_LIST_PROF(C)
56 #undef C
57 top_addresses_[Top::k_top_address_count] = NULL;
58 }
59
60 inline void PreallocatedMemoryThreadStart();
61 inline void PreallocatedMemoryThreadStop();
62
63 NoAllocationStringAllocator* preallocated_message_space_;
64 bool initialized_;
65 int stack_trace_nesting_level_;
66 StringStream* incomplete_message_;
67 // The preallocated memory thread singleton.
68 PreallocatedMemoryThread* preallocated_memory_thread_;
69 Address top_addresses_[Top::k_top_address_count + 1];
70 };
71
72
73 // TODO(isolates): We will be moving this to Isolate ASAP.
74 static TopState* GetTopState() {
75 static TopState top_state;
76 return &top_state;
77 }
78
79 42
80 v8::TryCatch* ThreadLocalTop::TryCatchHandler() { 43 v8::TryCatch* ThreadLocalTop::TryCatchHandler() {
81 return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address()); 44 return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address());
82 } 45 }
83 46
84 47
85 void ThreadLocalTop::Initialize() { 48 void ThreadLocalTop::Initialize() {
86 c_entry_fp_ = 0; 49 c_entry_fp_ = 0;
87 handler_ = 0; 50 handler_ = 0;
88 #ifdef ENABLE_LOGGING_AND_PROFILING 51 #ifdef ENABLE_LOGGING_AND_PROFILING
89 js_entry_sp_ = 0; 52 js_entry_sp_ = 0;
90 #endif 53 #endif
91 stack_is_cooked_ = false; 54 stack_is_cooked_ = false;
92 try_catch_handler_address_ = NULL; 55 try_catch_handler_address_ = NULL;
93 context_ = NULL; 56 context_ = NULL;
94 int id = ThreadManager::CurrentId(); 57 int id = ThreadManager::CurrentId();
95 thread_id_ = (id == 0) ? ThreadManager::kInvalidId : id; 58 thread_id_ = (id == 0) ? ThreadManager::kInvalidId : id;
96 external_caught_exception_ = false; 59 external_caught_exception_ = false;
97 failed_access_check_callback_ = NULL; 60 failed_access_check_callback_ = NULL;
98 save_context_ = NULL; 61 save_context_ = NULL;
99 catcher_ = NULL; 62 catcher_ = NULL;
100 } 63 }
101 64
102 65
103 Address Top::get_address_from_id(Top::AddressId id) { 66 Address Isolate::get_address_from_id(Isolate::AddressId id) {
104 return GetTopState()->top_addresses_[id]; 67 return isolate_addresses_[id];
105 } 68 }
106 69
107 70
108 char* Top::Iterate(ObjectVisitor* v, char* thread_storage) { 71 char* Isolate::Iterate(ObjectVisitor* v, char* thread_storage) {
109 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage); 72 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
110 Iterate(v, thread); 73 Iterate(v, thread);
111 return thread_storage + sizeof(ThreadLocalTop); 74 return thread_storage + sizeof(ThreadLocalTop);
112 } 75 }
113 76
114 77
115 void Top::IterateThread(ThreadVisitor* v) { 78 void Isolate::IterateThread(ThreadVisitor* v) {
116 v->VisitThread(thread_local()); 79 v->VisitThread(thread_local_top());
117 } 80 }
118 81
119 82
120 void Top::IterateThread(ThreadVisitor* v, char* t) { 83 void Isolate::IterateThread(ThreadVisitor* v, char* t) {
121 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t); 84 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
122 v->VisitThread(thread); 85 v->VisitThread(thread);
123 } 86 }
124 87
125 88
126 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { 89 void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
127 v->VisitPointer(&(thread->pending_exception_)); 90 v->VisitPointer(&(thread->pending_exception_));
128 v->VisitPointer(&(thread->pending_message_obj_)); 91 v->VisitPointer(&(thread->pending_message_obj_));
129 v->VisitPointer( 92 v->VisitPointer(
130 BitCast<Object**, Script**>(&(thread->pending_message_script_))); 93 BitCast<Object**, Script**>(&(thread->pending_message_script_)));
131 v->VisitPointer(BitCast<Object**, Context**>(&(thread->context_))); 94 v->VisitPointer(BitCast<Object**, Context**>(&(thread->context_)));
132 v->VisitPointer(&(thread->scheduled_exception_)); 95 v->VisitPointer(&(thread->scheduled_exception_));
133 96
134 for (v8::TryCatch* block = thread->TryCatchHandler(); 97 for (v8::TryCatch* block = thread->TryCatchHandler();
135 block != NULL; 98 block != NULL;
136 block = TRY_CATCH_FROM_ADDRESS(block->next_)) { 99 block = TRY_CATCH_FROM_ADDRESS(block->next_)) {
137 v->VisitPointer(BitCast<Object**, void**>(&(block->exception_))); 100 v->VisitPointer(BitCast<Object**, void**>(&(block->exception_)));
138 v->VisitPointer(BitCast<Object**, void**>(&(block->message_))); 101 v->VisitPointer(BitCast<Object**, void**>(&(block->message_)));
139 } 102 }
140 103
141 // Iterate over pointers on native execution stack. 104 // Iterate over pointers on native execution stack.
142 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { 105 for (StackFrameIterator it(thread); !it.done(); it.Advance()) {
143 it.frame()->Iterate(v); 106 it.frame()->Iterate(v);
144 } 107 }
145 } 108 }
146 109
147 110
148 void Top::Iterate(ObjectVisitor* v) { 111 void Isolate::Iterate(ObjectVisitor* v) {
149 ThreadLocalTop* current_t = thread_local(); 112 ThreadLocalTop* current_t = thread_local_top();
150 Iterate(v, current_t); 113 Iterate(v, current_t);
151 } 114 }
152 115
153 116
154 void Top::InitializeThreadLocal() { 117 void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
155 thread_local()->Initialize();
156 clear_pending_exception();
157 clear_pending_message();
158 clear_scheduled_exception();
159 }
160
161
162 // Create a dummy thread that will wait forever on a semaphore. The only
163 // purpose for this thread is to have some stack area to save essential data
164 // into for use by a stacks only core dump (aka minidump).
165 class PreallocatedMemoryThread: public Thread {
166 public:
167 char* data() {
168 if (data_ready_semaphore_ != NULL) {
169 // Initial access is guarded until the data has been published.
170 data_ready_semaphore_->Wait();
171 delete data_ready_semaphore_;
172 data_ready_semaphore_ = NULL;
173 }
174 return data_;
175 }
176
177 unsigned length() {
178 if (data_ready_semaphore_ != NULL) {
179 // Initial access is guarded until the data has been published.
180 data_ready_semaphore_->Wait();
181 delete data_ready_semaphore_;
182 data_ready_semaphore_ = NULL;
183 }
184 return length_;
185 }
186
187 // Stop the PreallocatedMemoryThread and release its resources.
188 void StopThread() {
189 keep_running_ = false;
190 wait_for_ever_semaphore_->Signal();
191
192 // Wait for the thread to terminate.
193 Join();
194
195 if (data_ready_semaphore_ != NULL) {
196 delete data_ready_semaphore_;
197 data_ready_semaphore_ = NULL;
198 }
199
200 delete wait_for_ever_semaphore_;
201 wait_for_ever_semaphore_ = NULL;
202 }
203
204 protected:
205 // When the thread starts running it will allocate a fixed number of bytes
206 // on the stack and publish the location of this memory for others to use.
207 void Run() {
208 EmbeddedVector<char, 15 * 1024> local_buffer;
209
210 // Initialize the buffer with a known good value.
211 OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
212 local_buffer.length());
213
214 // Publish the local buffer and signal its availability.
215 data_ = local_buffer.start();
216 length_ = local_buffer.length();
217 data_ready_semaphore_->Signal();
218
219 while (keep_running_) {
220 // This thread will wait here until the end of time.
221 wait_for_ever_semaphore_->Wait();
222 }
223
224 // Make sure we access the buffer after the wait to remove all possibility
225 // of it being optimized away.
226 OS::StrNCpy(local_buffer, "PreallocatedMemoryThread shutting down.\n",
227 local_buffer.length());
228 }
229
230
231 private:
232 PreallocatedMemoryThread()
233 : keep_running_(true),
234 wait_for_ever_semaphore_(OS::CreateSemaphore(0)),
235 data_ready_semaphore_(OS::CreateSemaphore(0)),
236 data_(NULL),
237 length_(0) {
238 }
239
240 // Used to make sure that the thread keeps looping even for spurious wakeups.
241 bool keep_running_;
242
243 // This semaphore is used by the PreallocatedMemoryThread to wait for ever.
244 Semaphore* wait_for_ever_semaphore_;
245 // Semaphore to signal that the data has been initialized.
246 Semaphore* data_ready_semaphore_;
247
248 // Location and size of the preallocated memory block.
249 char* data_;
250 unsigned length_;
251
252 friend class TopState;
253
254 DISALLOW_COPY_AND_ASSIGN(PreallocatedMemoryThread);
255 };
256
257
258 void TopState::PreallocatedMemoryThreadStart() {
259 if (preallocated_memory_thread_ != NULL) return;
260 preallocated_memory_thread_ = new PreallocatedMemoryThread();
261 preallocated_memory_thread_->Start();
262 }
263
264
265 void TopState::PreallocatedMemoryThreadStop() {
266 if (preallocated_memory_thread_ == NULL) return;
267 preallocated_memory_thread_->StopThread();
268 // Done with the thread entirely.
269 delete preallocated_memory_thread_;
270 preallocated_memory_thread_ = NULL;
271 }
272
273
274 void Top::Initialize() {
275 CHECK(!GetTopState()->initialized_);
276
277 InitializeThreadLocal();
278
279 // Only preallocate on the first initialization.
280 if (FLAG_preallocate_message_memory &&
281 (GetTopState()->preallocated_message_space_ == NULL)) {
282 // Start the thread which will set aside some memory.
283 GetTopState()->PreallocatedMemoryThreadStart();
284 GetTopState()->preallocated_message_space_ =
285 new NoAllocationStringAllocator(
286 GetTopState()->preallocated_memory_thread_->data(),
287 GetTopState()->preallocated_memory_thread_->length());
288 PreallocatedStorage::Init(
289 GetTopState()->preallocated_memory_thread_->length() / 4);
290 }
291 GetTopState()->initialized_ = true;
292 }
293
294
295 void Top::TearDown() {
296 if (GetTopState()->initialized_) {
297 // Remove the external reference to the preallocated stack memory.
298 if (GetTopState()->preallocated_message_space_ != NULL) {
299 delete GetTopState()->preallocated_message_space_;
300 GetTopState()->preallocated_message_space_ = NULL;
301 }
302
303 GetTopState()->PreallocatedMemoryThreadStop();
304 GetTopState()->initialized_ = false;
305 }
306 }
307
308
309 void Top::RegisterTryCatchHandler(v8::TryCatch* that) {
310 // The ARM simulator has a separate JS stack. We therefore register 118 // The ARM simulator has a separate JS stack. We therefore register
311 // the C++ try catch handler with the simulator and get back an 119 // the C++ try catch handler with the simulator and get back an
312 // address that can be used for comparisons with addresses into the 120 // address that can be used for comparisons with addresses into the
313 // JS stack. When running without the simulator, the address 121 // JS stack. When running without the simulator, the address
314 // returned will be the address of the C++ try catch handler itself. 122 // returned will be the address of the C++ try catch handler itself.
315 Address address = reinterpret_cast<Address>( 123 Address address = reinterpret_cast<Address>(
316 SimulatorStack::RegisterCTryCatch(reinterpret_cast<uintptr_t>(that))); 124 SimulatorStack::RegisterCTryCatch(reinterpret_cast<uintptr_t>(that)));
317 thread_local()->set_try_catch_handler_address(address); 125 thread_local_top()->set_try_catch_handler_address(address);
318 } 126 }
319 127
320 128
321 void Top::UnregisterTryCatchHandler(v8::TryCatch* that) { 129 void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) {
322 ASSERT(thread_local()->TryCatchHandler() == that); 130 ASSERT(thread_local_top()->TryCatchHandler() == that);
323 thread_local()->set_try_catch_handler_address( 131 thread_local_top()->set_try_catch_handler_address(
324 reinterpret_cast<Address>(that->next_)); 132 reinterpret_cast<Address>(that->next_));
325 thread_local()->catcher_ = NULL; 133 thread_local_top()->catcher_ = NULL;
326 SimulatorStack::UnregisterCTryCatch(); 134 SimulatorStack::UnregisterCTryCatch();
327 } 135 }
328 136
329 137
330 void Top::MarkCompactPrologue(bool is_compacting) { 138 void Isolate::MarkCompactPrologue(bool is_compacting) {
331 MarkCompactPrologue(is_compacting, thread_local()); 139 MarkCompactPrologue(is_compacting, thread_local_top());
332 } 140 }
333 141
334 142
335 void Top::MarkCompactPrologue(bool is_compacting, char* data) { 143 void Isolate::MarkCompactPrologue(bool is_compacting, char* data) {
336 MarkCompactPrologue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data)); 144 MarkCompactPrologue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
337 } 145 }
338 146
339 147
340 void Top::MarkCompactPrologue(bool is_compacting, ThreadLocalTop* thread) { 148 void Isolate::MarkCompactPrologue(bool is_compacting, ThreadLocalTop* thread) {
341 if (is_compacting) { 149 if (is_compacting) {
342 StackFrame::CookFramesForThread(thread); 150 StackFrame::CookFramesForThread(thread);
343 } 151 }
344 } 152 }
345 153
346 154
347 void Top::MarkCompactEpilogue(bool is_compacting, char* data) { 155 void Isolate::MarkCompactEpilogue(bool is_compacting, char* data) {
348 MarkCompactEpilogue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data)); 156 MarkCompactEpilogue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
349 } 157 }
350 158
351 159
352 void Top::MarkCompactEpilogue(bool is_compacting) { 160 void Isolate::MarkCompactEpilogue(bool is_compacting) {
353 MarkCompactEpilogue(is_compacting, thread_local()); 161 MarkCompactEpilogue(is_compacting, thread_local_top());
354 } 162 }
355 163
356 164
357 void Top::MarkCompactEpilogue(bool is_compacting, ThreadLocalTop* thread) { 165 void Isolate::MarkCompactEpilogue(bool is_compacting, ThreadLocalTop* thread) {
358 if (is_compacting) { 166 if (is_compacting) {
359 StackFrame::UncookFramesForThread(thread); 167 StackFrame::UncookFramesForThread(thread);
360 } 168 }
361 } 169 }
362 170
363 171
364 Handle<String> Top::StackTraceString() { 172 Handle<String> Isolate::StackTraceString() {
365 if (GetTopState()->stack_trace_nesting_level_ == 0) { 173 if (stack_trace_nesting_level_ == 0) {
366 GetTopState()->stack_trace_nesting_level_++; 174 stack_trace_nesting_level_++;
367 HeapStringAllocator allocator; 175 HeapStringAllocator allocator;
368 StringStream::ClearMentionedObjectCache(); 176 StringStream::ClearMentionedObjectCache();
369 StringStream accumulator(&allocator); 177 StringStream accumulator(&allocator);
370 GetTopState()->incomplete_message_ = &accumulator; 178 incomplete_message_ = &accumulator;
371 PrintStack(&accumulator); 179 PrintStack(&accumulator);
372 Handle<String> stack_trace = accumulator.ToString(); 180 Handle<String> stack_trace = accumulator.ToString();
373 GetTopState()->incomplete_message_ = NULL; 181 incomplete_message_ = NULL;
374 GetTopState()->stack_trace_nesting_level_ = 0; 182 stack_trace_nesting_level_ = 0;
375 return stack_trace; 183 return stack_trace;
376 } else if (GetTopState()->stack_trace_nesting_level_ == 1) { 184 } else if (stack_trace_nesting_level_ == 1) {
377 GetTopState()->stack_trace_nesting_level_++; 185 stack_trace_nesting_level_++;
378 OS::PrintError( 186 OS::PrintError(
379 "\n\nAttempt to print stack while printing stack (double fault)\n"); 187 "\n\nAttempt to print stack while printing stack (double fault)\n");
380 OS::PrintError( 188 OS::PrintError(
381 "If you are lucky you may find a partial stack dump on stdout.\n\n"); 189 "If you are lucky you may find a partial stack dump on stdout.\n\n");
382 GetTopState()->incomplete_message_->OutputToStdOut(); 190 incomplete_message_->OutputToStdOut();
383 return Factory::empty_symbol(); 191 return Factory::empty_symbol();
384 } else { 192 } else {
385 OS::Abort(); 193 OS::Abort();
386 // Unreachable 194 // Unreachable
387 return Factory::empty_symbol(); 195 return Factory::empty_symbol();
388 } 196 }
389 } 197 }
390 198
391 199
392 Local<StackTrace> Top::CaptureCurrentStackTrace( 200 Local<StackTrace> Isolate::CaptureCurrentStackTrace(
393 int frame_limit, StackTrace::StackTraceOptions options) { 201 int frame_limit, StackTrace::StackTraceOptions options) {
394 v8::HandleScope scope; 202 v8::HandleScope scope;
395 // Ensure no negative values. 203 // Ensure no negative values.
396 int limit = Max(frame_limit, 0); 204 int limit = Max(frame_limit, 0);
397 Handle<JSArray> stack_trace = Factory::NewJSArray(frame_limit); 205 Handle<JSArray> stack_trace = Factory::NewJSArray(frame_limit);
398 206
399 Handle<String> column_key = Factory::LookupAsciiSymbol("column"); 207 Handle<String> column_key = Factory::LookupAsciiSymbol("column");
400 Handle<String> line_key = Factory::LookupAsciiSymbol("lineNumber"); 208 Handle<String> line_key = Factory::LookupAsciiSymbol("lineNumber");
401 Handle<String> script_key = Factory::LookupAsciiSymbol("scriptName"); 209 Handle<String> script_key = Factory::LookupAsciiSymbol("scriptName");
402 Handle<String> function_key = Factory::LookupAsciiSymbol("functionName"); 210 Handle<String> function_key = Factory::LookupAsciiSymbol("functionName");
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame); 272 FixedArray::cast(stack_trace->elements())->set(frames_seen, *stackFrame);
465 frames_seen++; 273 frames_seen++;
466 it.Advance(); 274 it.Advance();
467 } 275 }
468 276
469 stack_trace->set_length(Smi::FromInt(frames_seen)); 277 stack_trace->set_length(Smi::FromInt(frames_seen));
470 return scope.Close(Utils::StackTraceToLocal(stack_trace)); 278 return scope.Close(Utils::StackTraceToLocal(stack_trace));
471 } 279 }
472 280
473 281
474 void Top::PrintStack() { 282 void Isolate::PrintStack() {
475 if (GetTopState()->stack_trace_nesting_level_ == 0) { 283 if (stack_trace_nesting_level_ == 0) {
476 GetTopState()->stack_trace_nesting_level_++; 284 stack_trace_nesting_level_++;
477 285
478 StringAllocator* allocator; 286 StringAllocator* allocator;
479 if (GetTopState()->preallocated_message_space_ == NULL) { 287 if (preallocated_message_space_ == NULL) {
480 allocator = new HeapStringAllocator(); 288 allocator = new HeapStringAllocator();
481 } else { 289 } else {
482 allocator = GetTopState()->preallocated_message_space_; 290 allocator = preallocated_message_space_;
483 } 291 }
484 292
485 NativeAllocationChecker allocation_checker( 293 NativeAllocationChecker allocation_checker(
486 !FLAG_preallocate_message_memory ? 294 !FLAG_preallocate_message_memory ?
487 NativeAllocationChecker::ALLOW : 295 NativeAllocationChecker::ALLOW :
488 NativeAllocationChecker::DISALLOW); 296 NativeAllocationChecker::DISALLOW);
489 297
490 StringStream::ClearMentionedObjectCache(); 298 StringStream::ClearMentionedObjectCache();
491 StringStream accumulator(allocator); 299 StringStream accumulator(allocator);
492 GetTopState()->incomplete_message_ = &accumulator; 300 incomplete_message_ = &accumulator;
493 PrintStack(&accumulator); 301 PrintStack(&accumulator);
494 accumulator.OutputToStdOut(); 302 accumulator.OutputToStdOut();
495 accumulator.Log(); 303 accumulator.Log();
496 GetTopState()->incomplete_message_ = NULL; 304 incomplete_message_ = NULL;
497 GetTopState()->stack_trace_nesting_level_ = 0; 305 stack_trace_nesting_level_ = 0;
498 if (GetTopState()->preallocated_message_space_ == NULL) { 306 if (preallocated_message_space_ == NULL) {
499 // Remove the HeapStringAllocator created above. 307 // Remove the HeapStringAllocator created above.
500 delete allocator; 308 delete allocator;
501 } 309 }
502 } else if (GetTopState()->stack_trace_nesting_level_ == 1) { 310 } else if (stack_trace_nesting_level_ == 1) {
503 GetTopState()->stack_trace_nesting_level_++; 311 stack_trace_nesting_level_++;
504 OS::PrintError( 312 OS::PrintError(
505 "\n\nAttempt to print stack while printing stack (double fault)\n"); 313 "\n\nAttempt to print stack while printing stack (double fault)\n");
506 OS::PrintError( 314 OS::PrintError(
507 "If you are lucky you may find a partial stack dump on stdout.\n\n"); 315 "If you are lucky you may find a partial stack dump on stdout.\n\n");
508 GetTopState()->incomplete_message_->OutputToStdOut(); 316 incomplete_message_->OutputToStdOut();
509 } 317 }
510 } 318 }
511 319
512 320
513 static void PrintFrames(StringStream* accumulator, 321 static void PrintFrames(StringStream* accumulator,
514 StackFrame::PrintMode mode) { 322 StackFrame::PrintMode mode) {
515 StackFrameIterator it; 323 StackFrameIterator it;
516 for (int i = 0; !it.done(); it.Advance()) { 324 for (int i = 0; !it.done(); it.Advance()) {
517 it.frame()->Print(accumulator, mode, i++); 325 it.frame()->Print(accumulator, mode, i++);
518 } 326 }
519 } 327 }
520 328
521 329
522 void Top::PrintStack(StringStream* accumulator) { 330 void Isolate::PrintStack(StringStream* accumulator) {
523 // The MentionedObjectCache is not GC-proof at the moment. 331 // The MentionedObjectCache is not GC-proof at the moment.
524 AssertNoAllocation nogc; 332 AssertNoAllocation nogc;
525 ASSERT(StringStream::IsMentionedObjectCacheClear()); 333 ASSERT(StringStream::IsMentionedObjectCacheClear());
526 334
527 // Avoid printing anything if there are no frames. 335 // Avoid printing anything if there are no frames.
528 if (c_entry_fp(thread_local()) == 0) return; 336 if (c_entry_fp(thread_local_top()) == 0) return;
529 337
530 accumulator->Add( 338 accumulator->Add(
531 "\n==== Stack trace ============================================\n\n"); 339 "\n==== Stack trace ============================================\n\n");
532 PrintFrames(accumulator, StackFrame::OVERVIEW); 340 PrintFrames(accumulator, StackFrame::OVERVIEW);
533 341
534 accumulator->Add( 342 accumulator->Add(
535 "\n==== Details ================================================\n\n"); 343 "\n==== Details ================================================\n\n");
536 PrintFrames(accumulator, StackFrame::DETAILS); 344 PrintFrames(accumulator, StackFrame::DETAILS);
537 345
538 accumulator->PrintMentionedObjectCache(); 346 accumulator->PrintMentionedObjectCache();
539 accumulator->Add("=====================\n\n"); 347 accumulator->Add("=====================\n\n");
540 } 348 }
541 349
542 350
543 void Top::SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback) { 351 void Isolate::SetFailedAccessCheckCallback(
544 ASSERT(thread_local()->failed_access_check_callback_ == NULL); 352 v8::FailedAccessCheckCallback callback) {
545 thread_local()->failed_access_check_callback_ = callback; 353 ASSERT(thread_local_top()->failed_access_check_callback_ == NULL);
354 thread_local_top()->failed_access_check_callback_ = callback;
546 } 355 }
547 356
548 357
549 void Top::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) { 358 void Isolate::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) {
550 if (!thread_local()->failed_access_check_callback_) return; 359 if (!thread_local_top()->failed_access_check_callback_) return;
551 360
552 ASSERT(receiver->IsAccessCheckNeeded()); 361 ASSERT(receiver->IsAccessCheckNeeded());
553 ASSERT(Top::context()); 362 ASSERT(context());
554 // The callers of this method are not expecting a GC. 363 // The callers of this method are not expecting a GC.
555 AssertNoAllocation no_gc; 364 AssertNoAllocation no_gc;
556 365
557 // Get the data object from access check info. 366 // Get the data object from access check info.
558 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); 367 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
559 if (!constructor->shared()->IsApiFunction()) return; 368 if (!constructor->shared()->IsApiFunction()) return;
560 Object* data_obj = 369 Object* data_obj =
561 constructor->shared()->get_api_func_data()->access_check_info(); 370 constructor->shared()->get_api_func_data()->access_check_info();
562 if (data_obj == HEAP->undefined_value()) return; 371 if (data_obj == heap_.undefined_value()) return;
563 372
564 HandleScope scope; 373 HandleScope scope;
565 Handle<JSObject> receiver_handle(receiver); 374 Handle<JSObject> receiver_handle(receiver);
566 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data()); 375 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());
567 thread_local()->failed_access_check_callback_( 376 thread_local_top()->failed_access_check_callback_(
568 v8::Utils::ToLocal(receiver_handle), 377 v8::Utils::ToLocal(receiver_handle),
569 type, 378 type,
570 v8::Utils::ToLocal(data)); 379 v8::Utils::ToLocal(data));
571 } 380 }
572 381
573 382
574 enum MayAccessDecision { 383 enum MayAccessDecision {
575 YES, NO, UNKNOWN 384 YES, NO, UNKNOWN
576 }; 385 };
577 386
578 387
579 static MayAccessDecision MayAccessPreCheck(JSObject* receiver, 388 static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
389 JSObject* receiver,
580 v8::AccessType type) { 390 v8::AccessType type) {
581 // During bootstrapping, callback functions are not enabled yet. 391 // During bootstrapping, callback functions are not enabled yet.
582 if (Bootstrapper::IsActive()) return YES; 392 if (Bootstrapper::IsActive()) return YES;
583 393
584 if (receiver->IsJSGlobalProxy()) { 394 if (receiver->IsJSGlobalProxy()) {
585 Object* receiver_context = JSGlobalProxy::cast(receiver)->context(); 395 Object* receiver_context = JSGlobalProxy::cast(receiver)->context();
586 if (!receiver_context->IsContext()) return NO; 396 if (!receiver_context->IsContext()) return NO;
587 397
588 // Get the global context of current top context. 398 // Get the global context of current top context.
589 // avoid using Top::global_context() because it uses Handle. 399 // avoid using Isolate::global_context() because it uses Handle.
590 Context* global_context = Top::context()->global()->global_context(); 400 Context* global_context = isolate->context()->global()->global_context();
591 if (receiver_context == global_context) return YES; 401 if (receiver_context == global_context) return YES;
592 402
593 if (Context::cast(receiver_context)->security_token() == 403 if (Context::cast(receiver_context)->security_token() ==
594 global_context->security_token()) 404 global_context->security_token())
595 return YES; 405 return YES;
596 } 406 }
597 407
598 return UNKNOWN; 408 return UNKNOWN;
599 } 409 }
600 410
601 411
602 bool Top::MayNamedAccess(JSObject* receiver, Object* key, v8::AccessType type) { 412 bool Isolate::MayNamedAccess(JSObject* receiver, Object* key,
413 v8::AccessType type) {
603 ASSERT(receiver->IsAccessCheckNeeded()); 414 ASSERT(receiver->IsAccessCheckNeeded());
604 415
605 // The callers of this method are not expecting a GC. 416 // The callers of this method are not expecting a GC.
606 AssertNoAllocation no_gc; 417 AssertNoAllocation no_gc;
607 418
608 // Skip checks for hidden properties access. Note, we do not 419 // Skip checks for hidden properties access. Note, we do not
609 // require existence of a context in this case. 420 // require existence of a context in this case.
610 if (key == HEAP->hidden_symbol()) return true; 421 if (key == heap_.hidden_symbol()) return true;
611 422
612 // Check for compatibility between the security tokens in the 423 // Check for compatibility between the security tokens in the
613 // current lexical context and the accessed object. 424 // current lexical context and the accessed object.
614 ASSERT(Top::context()); 425 ASSERT(context());
615 426
616 MayAccessDecision decision = MayAccessPreCheck(receiver, type); 427 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
617 if (decision != UNKNOWN) return decision == YES; 428 if (decision != UNKNOWN) return decision == YES;
618 429
619 // Get named access check callback 430 // Get named access check callback
620 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); 431 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
621 if (!constructor->shared()->IsApiFunction()) return false; 432 if (!constructor->shared()->IsApiFunction()) return false;
622 433
623 Object* data_obj = 434 Object* data_obj =
624 constructor->shared()->get_api_func_data()->access_check_info(); 435 constructor->shared()->get_api_func_data()->access_check_info();
625 if (data_obj == HEAP->undefined_value()) return false; 436 if (data_obj == heap_.undefined_value()) return false;
626 437
627 Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback(); 438 Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback();
628 v8::NamedSecurityCallback callback = 439 v8::NamedSecurityCallback callback =
629 v8::ToCData<v8::NamedSecurityCallback>(fun_obj); 440 v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
630 441
631 if (!callback) return false; 442 if (!callback) return false;
632 443
633 HandleScope scope; 444 HandleScope scope;
634 Handle<JSObject> receiver_handle(receiver); 445 Handle<JSObject> receiver_handle(receiver);
635 Handle<Object> key_handle(key); 446 Handle<Object> key_handle(key);
636 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data()); 447 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());
637 LOG(ApiNamedSecurityCheck(key)); 448 LOG(ApiNamedSecurityCheck(key));
638 bool result = false; 449 bool result = false;
639 { 450 {
640 // Leaving JavaScript. 451 // Leaving JavaScript.
641 VMState state(EXTERNAL); 452 VMState state(EXTERNAL);
642 result = callback(v8::Utils::ToLocal(receiver_handle), 453 result = callback(v8::Utils::ToLocal(receiver_handle),
643 v8::Utils::ToLocal(key_handle), 454 v8::Utils::ToLocal(key_handle),
644 type, 455 type,
645 v8::Utils::ToLocal(data)); 456 v8::Utils::ToLocal(data));
646 } 457 }
647 return result; 458 return result;
648 } 459 }
649 460
650 461
651 bool Top::MayIndexedAccess(JSObject* receiver, 462 bool Isolate::MayIndexedAccess(JSObject* receiver,
652 uint32_t index, 463 uint32_t index,
653 v8::AccessType type) { 464 v8::AccessType type) {
654 ASSERT(receiver->IsAccessCheckNeeded()); 465 ASSERT(receiver->IsAccessCheckNeeded());
655 // Check for compatibility between the security tokens in the 466 // Check for compatibility between the security tokens in the
656 // current lexical context and the accessed object. 467 // current lexical context and the accessed object.
657 ASSERT(Top::context()); 468 ASSERT(context());
658 // The callers of this method are not expecting a GC. 469 // The callers of this method are not expecting a GC.
659 AssertNoAllocation no_gc; 470 AssertNoAllocation no_gc;
660 471
661 MayAccessDecision decision = MayAccessPreCheck(receiver, type); 472 MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
662 if (decision != UNKNOWN) return decision == YES; 473 if (decision != UNKNOWN) return decision == YES;
663 474
664 // Get indexed access check callback 475 // Get indexed access check callback
665 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); 476 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
666 if (!constructor->shared()->IsApiFunction()) return false; 477 if (!constructor->shared()->IsApiFunction()) return false;
667 478
668 Object* data_obj = 479 Object* data_obj =
669 constructor->shared()->get_api_func_data()->access_check_info(); 480 constructor->shared()->get_api_func_data()->access_check_info();
670 if (data_obj == HEAP->undefined_value()) return false; 481 if (data_obj == heap_.undefined_value()) return false;
671 482
672 Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback(); 483 Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback();
673 v8::IndexedSecurityCallback callback = 484 v8::IndexedSecurityCallback callback =
674 v8::ToCData<v8::IndexedSecurityCallback>(fun_obj); 485 v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
675 486
676 if (!callback) return false; 487 if (!callback) return false;
677 488
678 HandleScope scope; 489 HandleScope scope;
679 Handle<JSObject> receiver_handle(receiver); 490 Handle<JSObject> receiver_handle(receiver);
680 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data()); 491 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());
681 LOG(ApiIndexedSecurityCheck(index)); 492 LOG(ApiIndexedSecurityCheck(index));
682 bool result = false; 493 bool result = false;
683 { 494 {
684 // Leaving JavaScript. 495 // Leaving JavaScript.
685 VMState state(EXTERNAL); 496 VMState state(EXTERNAL);
686 result = callback(v8::Utils::ToLocal(receiver_handle), 497 result = callback(v8::Utils::ToLocal(receiver_handle),
687 index, 498 index,
688 type, 499 type,
689 v8::Utils::ToLocal(data)); 500 v8::Utils::ToLocal(data));
690 } 501 }
691 return result; 502 return result;
692 } 503 }
693 504
694 505
695 const char* Top::kStackOverflowMessage = 506 const char* Isolate::kStackOverflowMessage =
696 "Uncaught RangeError: Maximum call stack size exceeded"; 507 "Uncaught RangeError: Maximum call stack size exceeded";
697 508
698 509
699 Failure* Top::StackOverflow() { 510 Failure* Isolate::StackOverflow() {
700 HandleScope scope; 511 HandleScope scope;
701 Handle<String> key = Factory::stack_overflow_symbol(); 512 Handle<String> key = Factory::stack_overflow_symbol();
702 Handle<JSObject> boilerplate = 513 Handle<JSObject> boilerplate =
703 Handle<JSObject>::cast(GetProperty(Top::builtins(), key)); 514 Handle<JSObject>::cast(GetProperty(builtins(), key));
704 Handle<Object> exception = Copy(boilerplate); 515 Handle<Object> exception = Copy(boilerplate);
705 // TODO(1240995): To avoid having to call JavaScript code to compute 516 // TODO(1240995): To avoid having to call JavaScript code to compute
706 // the message for stack overflow exceptions which is very likely to 517 // the message for stack overflow exceptions which is very likely to
707 // double fault with another stack overflow exception, we use a 518 // double fault with another stack overflow exception, we use a
708 // precomputed message. This is somewhat problematic in that it 519 // precomputed message. This is somewhat problematic in that it
709 // doesn't use ReportUncaughtException to determine the location 520 // doesn't use ReportUncaughtException to determine the location
710 // from where the exception occurred. It should probably be 521 // from where the exception occurred. It should probably be
711 // reworked. 522 // reworked.
712 DoThrow(*exception, NULL, kStackOverflowMessage); 523 DoThrow(*exception, NULL, kStackOverflowMessage);
713 return Failure::Exception(); 524 return Failure::Exception();
714 } 525 }
715 526
716 527
717 Failure* Top::TerminateExecution() { 528 Failure* Isolate::TerminateExecution() {
718 DoThrow(HEAP->termination_exception(), NULL, NULL); 529 DoThrow(heap_.termination_exception(), NULL, NULL);
719 return Failure::Exception(); 530 return Failure::Exception();
720 } 531 }
721 532
722 533
723 Failure* Top::Throw(Object* exception, MessageLocation* location) { 534 Failure* Isolate::Throw(Object* exception, MessageLocation* location) {
724 DoThrow(exception, location, NULL); 535 DoThrow(exception, location, NULL);
725 return Failure::Exception(); 536 return Failure::Exception();
726 } 537 }
727 538
728 539
729 Failure* Top::ReThrow(Object* exception, MessageLocation* location) { 540 Failure* Isolate::ReThrow(Object* exception, MessageLocation* location) {
730 // Set the exception being re-thrown. 541 // Set the exception being re-thrown.
731 set_pending_exception(exception); 542 set_pending_exception(exception);
732 return Failure::Exception(); 543 return Failure::Exception();
733 } 544 }
734 545
735 546
736 Failure* Top::ThrowIllegalOperation() { 547 Failure* Isolate::ThrowIllegalOperation() {
737 return Throw(HEAP->illegal_access_symbol()); 548 return Throw(heap_.illegal_access_symbol());
738 } 549 }
739 550
740 551
741 void Top::ScheduleThrow(Object* exception) { 552 void Isolate::ScheduleThrow(Object* exception) {
742 // When scheduling a throw we first throw the exception to get the 553 // When scheduling a throw we first throw the exception to get the
743 // error reporting if it is uncaught before rescheduling it. 554 // error reporting if it is uncaught before rescheduling it.
744 Throw(exception); 555 Throw(exception);
745 thread_local()->scheduled_exception_ = pending_exception(); 556 thread_local_top()->scheduled_exception_ = pending_exception();
746 thread_local()->external_caught_exception_ = false; 557 thread_local_top()->external_caught_exception_ = false;
747 clear_pending_exception(); 558 clear_pending_exception();
748 } 559 }
749 560
750 561
751 Object* Top::PromoteScheduledException() { 562 Object* Isolate::PromoteScheduledException() {
752 Object* thrown = scheduled_exception(); 563 Object* thrown = scheduled_exception();
753 clear_scheduled_exception(); 564 clear_scheduled_exception();
754 // Re-throw the exception to avoid getting repeated error reporting. 565 // Re-throw the exception to avoid getting repeated error reporting.
755 return ReThrow(thrown); 566 return ReThrow(thrown);
756 } 567 }
757 568
758 569
759 void Top::PrintCurrentStackTrace(FILE* out) { 570 void Isolate::PrintCurrentStackTrace(FILE* out) {
760 StackTraceFrameIterator it; 571 StackTraceFrameIterator it;
761 while (!it.done()) { 572 while (!it.done()) {
762 HandleScope scope; 573 HandleScope scope;
763 // Find code position if recorded in relocation info. 574 // Find code position if recorded in relocation info.
764 JavaScriptFrame* frame = it.frame(); 575 JavaScriptFrame* frame = it.frame();
765 int pos = frame->code()->SourcePosition(frame->pc()); 576 int pos = frame->code()->SourcePosition(frame->pc());
766 Handle<Object> pos_obj(Smi::FromInt(pos)); 577 Handle<Object> pos_obj(Smi::FromInt(pos));
767 // Fetch function and receiver. 578 // Fetch function and receiver.
768 Handle<JSFunction> fun(JSFunction::cast(frame->function())); 579 Handle<JSFunction> fun(JSFunction::cast(frame->function()));
769 Handle<Object> recv(frame->receiver()); 580 Handle<Object> recv(frame->receiver());
770 // Advance to the next JavaScript frame and determine if the 581 // Advance to the next JavaScript frame and determine if the
771 // current frame is the top-level frame. 582 // current frame is the top-level frame.
772 it.Advance(); 583 it.Advance();
773 Handle<Object> is_top_level = it.done() 584 Handle<Object> is_top_level = it.done()
774 ? Factory::true_value() 585 ? Factory::true_value()
775 : Factory::false_value(); 586 : Factory::false_value();
776 // Generate and print stack trace line. 587 // Generate and print stack trace line.
777 Handle<String> line = 588 Handle<String> line =
778 Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level); 589 Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
779 if (line->length() > 0) { 590 if (line->length() > 0) {
780 line->PrintOn(out); 591 line->PrintOn(out);
781 fprintf(out, "\n"); 592 fprintf(out, "\n");
782 } 593 }
783 } 594 }
784 } 595 }
785 596
786 597
787 void Top::ComputeLocation(MessageLocation* target) { 598 void Isolate::ComputeLocation(MessageLocation* target) {
788 *target = MessageLocation(Handle<Script>(HEAP->empty_script()), -1, -1); 599 *target = MessageLocation(Handle<Script>(heap_.empty_script()), -1, -1);
789 StackTraceFrameIterator it; 600 StackTraceFrameIterator it;
790 if (!it.done()) { 601 if (!it.done()) {
791 JavaScriptFrame* frame = it.frame(); 602 JavaScriptFrame* frame = it.frame();
792 JSFunction* fun = JSFunction::cast(frame->function()); 603 JSFunction* fun = JSFunction::cast(frame->function());
793 Object* script = fun->shared()->script(); 604 Object* script = fun->shared()->script();
794 if (script->IsScript() && 605 if (script->IsScript() &&
795 !(Script::cast(script)->source()->IsUndefined())) { 606 !(Script::cast(script)->source()->IsUndefined())) {
796 int pos = frame->code()->SourcePosition(frame->pc()); 607 int pos = frame->code()->SourcePosition(frame->pc());
797 // Compute the location from the function and the reloc info. 608 // Compute the location from the function and the reloc info.
798 Handle<Script> casted_script(Script::cast(script)); 609 Handle<Script> casted_script(Script::cast(script));
799 *target = MessageLocation(casted_script, pos, pos + 1); 610 *target = MessageLocation(casted_script, pos, pos + 1);
800 } 611 }
801 } 612 }
802 } 613 }
803 614
804 615
805 void Top::ReportUncaughtException(Handle<Object> exception, 616 void Isolate::ReportUncaughtException(Handle<Object> exception,
806 MessageLocation* location, 617 MessageLocation* location,
807 Handle<String> stack_trace) { 618 Handle<String> stack_trace) {
808 Handle<Object> message; 619 Handle<Object> message;
809 if (!Bootstrapper::IsActive()) { 620 if (!Bootstrapper::IsActive()) {
810 // It's not safe to try to make message objects while the bootstrapper 621 // It's not safe to try to make message objects while the bootstrapper
811 // is active since the infrastructure may not have been properly 622 // is active since the infrastructure may not have been properly
812 // initialized. 623 // initialized.
813 message = 624 message =
814 MessageHandler::MakeMessageObject("uncaught_exception", 625 MessageHandler::MakeMessageObject("uncaught_exception",
815 location, 626 location,
816 HandleVector<Object>(&exception, 1), 627 HandleVector<Object>(&exception, 1),
817 stack_trace); 628 stack_trace);
818 } 629 }
819 // Report the uncaught exception. 630 // Report the uncaught exception.
820 MessageHandler::ReportMessage(location, message); 631 MessageHandler::ReportMessage(location, message);
821 } 632 }
822 633
823 634
824 bool Top::ShouldReturnException(bool* is_caught_externally, 635 bool Isolate::ShouldReturnException(bool* is_caught_externally,
825 bool catchable_by_javascript) { 636 bool catchable_by_javascript) {
826 // Find the top-most try-catch handler. 637 // Find the top-most try-catch handler.
827 StackHandler* handler = 638 StackHandler* handler =
828 StackHandler::FromAddress(Top::handler(thread_local())); 639 StackHandler::FromAddress(Isolate::handler(thread_local_top()));
829 while (handler != NULL && !handler->is_try_catch()) { 640 while (handler != NULL && !handler->is_try_catch()) {
830 handler = handler->next(); 641 handler = handler->next();
831 } 642 }
832 643
833 // Get the address of the external handler so we can compare the address to 644 // Get the address of the external handler so we can compare the address to
834 // determine which one is closer to the top of the stack. 645 // determine which one is closer to the top of the stack.
835 Address external_handler_address = 646 Address external_handler_address =
836 thread_local()->try_catch_handler_address(); 647 thread_local_top()->try_catch_handler_address();
837 648
838 // The exception has been externally caught if and only if there is 649 // The exception has been externally caught if and only if there is
839 // an external handler which is on top of the top-most try-catch 650 // an external handler which is on top of the top-most try-catch
840 // handler. 651 // handler.
841 *is_caught_externally = external_handler_address != NULL && 652 *is_caught_externally = external_handler_address != NULL &&
842 (handler == NULL || handler->address() > external_handler_address || 653 (handler == NULL || handler->address() > external_handler_address ||
843 !catchable_by_javascript); 654 !catchable_by_javascript);
844 655
845 if (*is_caught_externally) { 656 if (*is_caught_externally) {
846 // Only report the exception if the external handler is verbose. 657 // Only report the exception if the external handler is verbose.
847 return thread_local()->TryCatchHandler()->is_verbose_; 658 return thread_local_top()->TryCatchHandler()->is_verbose_;
848 } else { 659 } else {
849 // Report the exception if it isn't caught by JavaScript code. 660 // Report the exception if it isn't caught by JavaScript code.
850 return handler == NULL; 661 return handler == NULL;
851 } 662 }
852 } 663 }
853 664
854 665
855 void Top::DoThrow(Object* exception, 666 void Isolate::DoThrow(Object* exception,
856 MessageLocation* location, 667 MessageLocation* location,
857 const char* message) { 668 const char* message) {
858 ASSERT(!has_pending_exception()); 669 ASSERT(!has_pending_exception());
859 670
860 HandleScope scope; 671 HandleScope scope;
861 Handle<Object> exception_handle(exception); 672 Handle<Object> exception_handle(exception);
862 673
863 // Determine reporting and whether the exception is caught externally. 674 // Determine reporting and whether the exception is caught externally.
864 bool is_caught_externally = false; 675 bool is_caught_externally = false;
865 bool is_out_of_memory = exception == Failure::OutOfMemoryException(); 676 bool is_out_of_memory = exception == Failure::OutOfMemoryException();
866 bool is_termination_exception = exception == HEAP->termination_exception(); 677 bool is_termination_exception = exception == heap_.termination_exception();
867 bool catchable_by_javascript = !is_termination_exception && !is_out_of_memory; 678 bool catchable_by_javascript = !is_termination_exception && !is_out_of_memory;
868 bool should_return_exception = 679 bool should_return_exception =
869 ShouldReturnException(&is_caught_externally, catchable_by_javascript); 680 ShouldReturnException(&is_caught_externally, catchable_by_javascript);
870 bool report_exception = catchable_by_javascript && should_return_exception; 681 bool report_exception = catchable_by_javascript && should_return_exception;
871 682
872 #ifdef ENABLE_DEBUGGER_SUPPORT 683 #ifdef ENABLE_DEBUGGER_SUPPORT
873 // Notify debugger of exception. 684 // Notify debugger of exception.
874 if (catchable_by_javascript) { 685 if (catchable_by_javascript) {
875 Debugger::OnException(exception_handle, report_exception); 686 Debugger::OnException(exception_handle, report_exception);
876 } 687 }
877 #endif 688 #endif
878 689
879 // Generate the message. 690 // Generate the message.
880 Handle<Object> message_obj; 691 Handle<Object> message_obj;
881 MessageLocation potential_computed_location; 692 MessageLocation potential_computed_location;
882 bool try_catch_needs_message = 693 bool try_catch_needs_message =
883 is_caught_externally && 694 is_caught_externally &&
884 thread_local()->TryCatchHandler()->capture_message_; 695 thread_local_top()->TryCatchHandler()->capture_message_;
885 if (report_exception || try_catch_needs_message) { 696 if (report_exception || try_catch_needs_message) {
886 if (location == NULL) { 697 if (location == NULL) {
887 // If no location was specified we use a computed one instead 698 // If no location was specified we use a computed one instead
888 ComputeLocation(&potential_computed_location); 699 ComputeLocation(&potential_computed_location);
889 location = &potential_computed_location; 700 location = &potential_computed_location;
890 } 701 }
891 if (!Bootstrapper::IsActive()) { 702 if (!Bootstrapper::IsActive()) {
892 // It's not safe to try to make message objects or collect stack 703 // It's not safe to try to make message objects or collect stack
893 // traces while the bootstrapper is active since the infrastructure 704 // traces while the bootstrapper is active since the infrastructure
894 // may not have been properly initialized. 705 // may not have been properly initialized.
895 Handle<String> stack_trace; 706 Handle<String> stack_trace;
896 if (FLAG_trace_exception) stack_trace = StackTraceString(); 707 if (FLAG_trace_exception) stack_trace = StackTraceString();
897 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", 708 message_obj = MessageHandler::MakeMessageObject("uncaught_exception",
898 location, HandleVector<Object>(&exception_handle, 1), stack_trace); 709 location, HandleVector<Object>(&exception_handle, 1), stack_trace);
899 } 710 }
900 } 711 }
901 712
902 // Save the message for reporting if the the exception remains uncaught. 713 // Save the message for reporting if the the exception remains uncaught.
903 thread_local()->has_pending_message_ = report_exception; 714 thread_local_top()->has_pending_message_ = report_exception;
904 thread_local()->pending_message_ = message; 715 thread_local_top()->pending_message_ = message;
905 if (!message_obj.is_null()) { 716 if (!message_obj.is_null()) {
906 thread_local()->pending_message_obj_ = *message_obj; 717 thread_local_top()->pending_message_obj_ = *message_obj;
907 if (location != NULL) { 718 if (location != NULL) {
908 thread_local()->pending_message_script_ = *location->script(); 719 thread_local_top()->pending_message_script_ = *location->script();
909 thread_local()->pending_message_start_pos_ = location->start_pos(); 720 thread_local_top()->pending_message_start_pos_ = location->start_pos();
910 thread_local()->pending_message_end_pos_ = location->end_pos(); 721 thread_local_top()->pending_message_end_pos_ = location->end_pos();
911 } 722 }
912 } 723 }
913 724
914 if (is_caught_externally) { 725 if (is_caught_externally) {
915 thread_local()->catcher_ = thread_local()->TryCatchHandler(); 726 thread_local_top()->catcher_ = thread_local_top()->TryCatchHandler();
916 } 727 }
917 728
918 // NOTE: Notifying the debugger or generating the message 729 // NOTE: Notifying the debugger or generating the message
919 // may have caused new exceptions. For now, we just ignore 730 // may have caused new exceptions. For now, we just ignore
920 // that and set the pending exception to the original one. 731 // that and set the pending exception to the original one.
921 set_pending_exception(*exception_handle); 732 set_pending_exception(*exception_handle);
922 } 733 }
923 734
924 735
925 void Top::ReportPendingMessages() { 736 void Isolate::ReportPendingMessages() {
926 ASSERT(has_pending_exception()); 737 ASSERT(has_pending_exception());
927 setup_external_caught(); 738 setup_external_caught();
928 // If the pending exception is OutOfMemoryException set out_of_memory in 739 // If the pending exception is OutOfMemoryException set out_of_memory in
929 // the global context. Note: We have to mark the global context here 740 // the global context. Note: We have to mark the global context here
930 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to 741 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
931 // set it. 742 // set it.
932 bool external_caught = thread_local()->external_caught_exception_; 743 bool external_caught = thread_local_top()->external_caught_exception_;
933 HandleScope scope; 744 HandleScope scope;
934 if (thread_local()->pending_exception_ == Failure::OutOfMemoryException()) { 745 if (thread_local_top()->pending_exception_ ==
746 Failure::OutOfMemoryException()) {
935 context()->mark_out_of_memory(); 747 context()->mark_out_of_memory();
936 } else if (thread_local()->pending_exception_ == 748 } else if (thread_local_top()->pending_exception_ ==
937 HEAP->termination_exception()) { 749 heap_.termination_exception()) {
938 if (external_caught) { 750 if (external_caught) {
939 thread_local()->TryCatchHandler()->can_continue_ = false; 751 thread_local_top()->TryCatchHandler()->can_continue_ = false;
940 thread_local()->TryCatchHandler()->exception_ = HEAP->null_value(); 752 thread_local_top()->TryCatchHandler()->exception_ = heap_.null_value();
941 } 753 }
942 } else { 754 } else {
943 Handle<Object> exception(pending_exception()); 755 Handle<Object> exception(pending_exception());
944 thread_local()->external_caught_exception_ = false; 756 thread_local_top()->external_caught_exception_ = false;
945 if (external_caught) { 757 if (external_caught) {
946 thread_local()->TryCatchHandler()->can_continue_ = true; 758 thread_local_top()->TryCatchHandler()->can_continue_ = true;
947 thread_local()->TryCatchHandler()->exception_ = 759 thread_local_top()->TryCatchHandler()->exception_ =
948 thread_local()->pending_exception_; 760 thread_local_top()->pending_exception_;
949 if (!thread_local()->pending_message_obj_->IsTheHole()) { 761 if (!thread_local_top()->pending_message_obj_->IsTheHole()) {
950 try_catch_handler()->message_ = thread_local()->pending_message_obj_; 762 try_catch_handler()->message_ =
763 thread_local_top()->pending_message_obj_;
951 } 764 }
952 } 765 }
953 if (thread_local()->has_pending_message_) { 766 if (thread_local_top()->has_pending_message_) {
954 thread_local()->has_pending_message_ = false; 767 thread_local_top()->has_pending_message_ = false;
955 if (thread_local()->pending_message_ != NULL) { 768 if (thread_local_top()->pending_message_ != NULL) {
956 MessageHandler::ReportMessage(thread_local()->pending_message_); 769 MessageHandler::ReportMessage(thread_local_top()->pending_message_);
957 } else if (!thread_local()->pending_message_obj_->IsTheHole()) { 770 } else if (!thread_local_top()->pending_message_obj_->IsTheHole()) {
958 Handle<Object> message_obj(thread_local()->pending_message_obj_); 771 Handle<Object> message_obj(thread_local_top()->pending_message_obj_);
959 if (thread_local()->pending_message_script_ != NULL) { 772 if (thread_local_top()->pending_message_script_ != NULL) {
960 Handle<Script> script(thread_local()->pending_message_script_); 773 Handle<Script> script(thread_local_top()->pending_message_script_);
961 int start_pos = thread_local()->pending_message_start_pos_; 774 int start_pos = thread_local_top()->pending_message_start_pos_;
962 int end_pos = thread_local()->pending_message_end_pos_; 775 int end_pos = thread_local_top()->pending_message_end_pos_;
963 MessageLocation location(script, start_pos, end_pos); 776 MessageLocation location(script, start_pos, end_pos);
964 MessageHandler::ReportMessage(&location, message_obj); 777 MessageHandler::ReportMessage(&location, message_obj);
965 } else { 778 } else {
966 MessageHandler::ReportMessage(NULL, message_obj); 779 MessageHandler::ReportMessage(NULL, message_obj);
967 } 780 }
968 } 781 }
969 } 782 }
970 thread_local()->external_caught_exception_ = external_caught; 783 thread_local_top()->external_caught_exception_ = external_caught;
971 set_pending_exception(*exception); 784 set_pending_exception(*exception);
972 } 785 }
973 clear_pending_message(); 786 clear_pending_message();
974 } 787 }
975 788
976 789
977 void Top::TraceException(bool flag) { 790 void Isolate::TraceException(bool flag) {
978 FLAG_trace_exception = flag; 791 FLAG_trace_exception = flag; // TODO(isolates): This is an unfortunate use.
979 } 792 }
980 793
981 794
982 bool Top::OptionalRescheduleException(bool is_bottom_call) { 795 bool Isolate::OptionalRescheduleException(bool is_bottom_call) {
983 // Allways reschedule out of memory exceptions. 796 // Allways reschedule out of memory exceptions.
984 if (!is_out_of_memory()) { 797 if (!is_out_of_memory()) {
985 bool is_termination_exception = 798 bool is_termination_exception =
986 pending_exception() == HEAP->termination_exception(); 799 pending_exception() == heap_.termination_exception();
987 800
988 // Do not reschedule the exception if this is the bottom call. 801 // Do not reschedule the exception if this is the bottom call.
989 bool clear_exception = is_bottom_call; 802 bool clear_exception = is_bottom_call;
990 803
991 if (is_termination_exception) { 804 if (is_termination_exception) {
992 if (is_bottom_call) { 805 if (is_bottom_call) {
993 thread_local()->external_caught_exception_ = false; 806 thread_local_top()->external_caught_exception_ = false;
994 clear_pending_exception(); 807 clear_pending_exception();
995 return false; 808 return false;
996 } 809 }
997 } else if (thread_local()->external_caught_exception_) { 810 } else if (thread_local_top()->external_caught_exception_) {
998 // If the exception is externally caught, clear it if there are no 811 // If the exception is externally caught, clear it if there are no
999 // JavaScript frames on the way to the C++ frame that has the 812 // JavaScript frames on the way to the C++ frame that has the
1000 // external handler. 813 // external handler.
1001 ASSERT(thread_local()->try_catch_handler_address() != NULL); 814 ASSERT(thread_local_top()->try_catch_handler_address() != NULL);
1002 Address external_handler_address = 815 Address external_handler_address =
1003 thread_local()->try_catch_handler_address(); 816 thread_local_top()->try_catch_handler_address();
1004 JavaScriptFrameIterator it; 817 JavaScriptFrameIterator it;
1005 if (it.done() || (it.frame()->sp() > external_handler_address)) { 818 if (it.done() || (it.frame()->sp() > external_handler_address)) {
1006 clear_exception = true; 819 clear_exception = true;
1007 } 820 }
1008 } 821 }
1009 822
1010 // Clear the exception if needed. 823 // Clear the exception if needed.
1011 if (clear_exception) { 824 if (clear_exception) {
1012 thread_local()->external_caught_exception_ = false; 825 thread_local_top()->external_caught_exception_ = false;
1013 clear_pending_exception(); 826 clear_pending_exception();
1014 return false; 827 return false;
1015 } 828 }
1016 } 829 }
1017 830
1018 // Reschedule the exception. 831 // Reschedule the exception.
1019 thread_local()->scheduled_exception_ = pending_exception(); 832 thread_local_top()->scheduled_exception_ = pending_exception();
1020 clear_pending_exception(); 833 clear_pending_exception();
1021 return true; 834 return true;
1022 } 835 }
1023 836
1024 837
1025 bool Top::is_out_of_memory() { 838 bool Isolate::is_out_of_memory() {
1026 if (has_pending_exception()) { 839 if (has_pending_exception()) {
1027 Object* e = pending_exception(); 840 Object* e = pending_exception();
1028 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) { 841 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1029 return true; 842 return true;
1030 } 843 }
1031 } 844 }
1032 if (has_scheduled_exception()) { 845 if (has_scheduled_exception()) {
1033 Object* e = scheduled_exception(); 846 Object* e = scheduled_exception();
1034 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) { 847 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1035 return true; 848 return true;
1036 } 849 }
1037 } 850 }
1038 return false; 851 return false;
1039 } 852 }
1040 853
1041 854
1042 Handle<Context> Top::global_context() { 855 Handle<Context> Isolate::global_context() {
1043 GlobalObject* global = thread_local()->context_->global(); 856 GlobalObject* global = thread_local_top()->context_->global();
1044 return Handle<Context>(global->global_context()); 857 return Handle<Context>(global->global_context());
1045 } 858 }
1046 859
1047 860
1048 Handle<Context> Top::GetCallingGlobalContext() { 861 Handle<Context> Isolate::GetCallingGlobalContext() {
1049 JavaScriptFrameIterator it; 862 JavaScriptFrameIterator it;
1050 #ifdef ENABLE_DEBUGGER_SUPPORT 863 #ifdef ENABLE_DEBUGGER_SUPPORT
1051 if (Debug::InDebugger()) { 864 if (Debug::InDebugger()) {
1052 while (!it.done()) { 865 while (!it.done()) {
1053 JavaScriptFrame* frame = it.frame(); 866 JavaScriptFrame* frame = it.frame();
1054 Context* context = Context::cast(frame->context()); 867 Context* context = Context::cast(frame->context());
1055 if (context->global_context() == *Debug::debug_context()) { 868 if (context->global_context() == *Debug::debug_context()) {
1056 it.Advance(); 869 it.Advance();
1057 } else { 870 } else {
1058 break; 871 break;
1059 } 872 }
1060 } 873 }
1061 } 874 }
1062 #endif // ENABLE_DEBUGGER_SUPPORT 875 #endif // ENABLE_DEBUGGER_SUPPORT
1063 if (it.done()) return Handle<Context>::null(); 876 if (it.done()) return Handle<Context>::null();
1064 JavaScriptFrame* frame = it.frame(); 877 JavaScriptFrame* frame = it.frame();
1065 Context* context = Context::cast(frame->context()); 878 Context* context = Context::cast(frame->context());
1066 return Handle<Context>(context->global_context()); 879 return Handle<Context>(context->global_context());
1067 } 880 }
1068 881
1069 882
1070 char* Top::ArchiveThread(char* to) { 883 char* Isolate::ArchiveThread(char* to) {
1071 memcpy(to, reinterpret_cast<char*>(thread_local()), sizeof(ThreadLocalTop)); 884 memcpy(to, reinterpret_cast<char*>(thread_local_top()),
885 sizeof(ThreadLocalTop));
1072 InitializeThreadLocal(); 886 InitializeThreadLocal();
1073 return to + sizeof(ThreadLocalTop); 887 return to + sizeof(ThreadLocalTop);
1074 } 888 }
1075 889
1076 890
1077 char* Top::RestoreThread(char* from) { 891 char* Isolate::RestoreThread(char* from) {
1078 memcpy(reinterpret_cast<char*>(thread_local()), from, sizeof(ThreadLocalTop)); 892 memcpy(reinterpret_cast<char*>(thread_local_top()), from,
893 sizeof(ThreadLocalTop));
1079 return from + sizeof(ThreadLocalTop); 894 return from + sizeof(ThreadLocalTop);
1080 } 895 }
1081 896
1082 897
1083 ExecutionAccess::ExecutionAccess() { 898 ExecutionAccess::ExecutionAccess() {
1084 Isolate::Current()->break_access()->Lock(); 899 Isolate::Current()->break_access()->Lock();
1085 } 900 }
1086 901
1087 902
1088 ExecutionAccess::~ExecutionAccess() { 903 ExecutionAccess::~ExecutionAccess() {
1089 Isolate::Current()->break_access()->Unlock(); 904 Isolate::Current()->break_access()->Unlock();
1090 } 905 }
1091 906
1092 907
1093 } } // namespace v8::internal 908 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/top.h ('k') | src/v8.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698