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

Side by Side Diff: src/top.cc

Issue 2720005: [Isolates] Begin removing [static] from Top.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' 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') | test/cctest/test-log-stack-tracer.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 ThreadLocalTop Top::thread_local_; 42 class PreallocatedMemoryThread;
43 43
44 NoAllocationStringAllocator* preallocated_message_space = NULL; 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 }
45 59
46 Address top_addresses[] = { 60 inline void PreallocatedMemoryThreadStart();
47 #define C(name) reinterpret_cast<Address>(Top::name()), 61 inline void PreallocatedMemoryThreadStop();
48 TOP_ADDRESS_LIST(C) 62
49 TOP_ADDRESS_LIST_PROF(C) 63 NoAllocationStringAllocator* preallocated_message_space_;
50 #undef C 64 bool initialized_;
51 NULL 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];
52 }; 70 };
53 71
54 72
73 // TODO(isolates): We will be moving this to Isolate ASAP.
74 static TopState top_state;
75
76
55 v8::TryCatch* ThreadLocalTop::TryCatchHandler() { 77 v8::TryCatch* ThreadLocalTop::TryCatchHandler() {
56 return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address()); 78 return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address());
57 } 79 }
58 80
59 81
60 void ThreadLocalTop::Initialize() { 82 void ThreadLocalTop::Initialize() {
61 c_entry_fp_ = 0; 83 c_entry_fp_ = 0;
62 handler_ = 0; 84 handler_ = 0;
63 #ifdef ENABLE_LOGGING_AND_PROFILING 85 #ifdef ENABLE_LOGGING_AND_PROFILING
64 js_entry_sp_ = 0; 86 js_entry_sp_ = 0;
65 #endif 87 #endif
66 stack_is_cooked_ = false; 88 stack_is_cooked_ = false;
67 try_catch_handler_address_ = NULL; 89 try_catch_handler_address_ = NULL;
68 context_ = NULL; 90 context_ = NULL;
69 int id = ThreadManager::CurrentId(); 91 int id = ThreadManager::CurrentId();
70 thread_id_ = (id == 0) ? ThreadManager::kInvalidId : id; 92 thread_id_ = (id == 0) ? ThreadManager::kInvalidId : id;
71 external_caught_exception_ = false; 93 external_caught_exception_ = false;
72 failed_access_check_callback_ = NULL; 94 failed_access_check_callback_ = NULL;
73 save_context_ = NULL; 95 save_context_ = NULL;
74 catcher_ = NULL; 96 catcher_ = NULL;
75 } 97 }
76 98
77 99
78 Address Top::get_address_from_id(Top::AddressId id) { 100 Address Top::get_address_from_id(Top::AddressId id) {
79 return top_addresses[id]; 101 return top_state.top_addresses_[id];
80 } 102 }
81 103
82 104
83 char* Top::Iterate(ObjectVisitor* v, char* thread_storage) { 105 char* Top::Iterate(ObjectVisitor* v, char* thread_storage) {
84 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage); 106 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
85 Iterate(v, thread); 107 Iterate(v, thread);
86 return thread_storage + sizeof(ThreadLocalTop); 108 return thread_storage + sizeof(ThreadLocalTop);
87 } 109 }
88 110
89 111
90 void Top::IterateThread(ThreadVisitor* v) { 112 void Top::IterateThread(ThreadVisitor* v) {
91 v->VisitThread(&thread_local_); 113 v->VisitThread(thread_local());
92 } 114 }
93 115
94 116
95 void Top::IterateThread(ThreadVisitor* v, char* t) { 117 void Top::IterateThread(ThreadVisitor* v, char* t) {
96 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t); 118 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
97 v->VisitThread(thread); 119 v->VisitThread(thread);
98 } 120 }
99 121
100 122
101 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { 123 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
(...skipping 12 matching lines...) Expand all
114 } 136 }
115 137
116 // Iterate over pointers on native execution stack. 138 // Iterate over pointers on native execution stack.
117 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { 139 for (StackFrameIterator it(thread); !it.done(); it.Advance()) {
118 it.frame()->Iterate(v); 140 it.frame()->Iterate(v);
119 } 141 }
120 } 142 }
121 143
122 144
123 void Top::Iterate(ObjectVisitor* v) { 145 void Top::Iterate(ObjectVisitor* v) {
124 ThreadLocalTop* current_t = &thread_local_; 146 ThreadLocalTop* current_t = thread_local();
125 Iterate(v, current_t); 147 Iterate(v, current_t);
126 } 148 }
127 149
128 150
129 void Top::InitializeThreadLocal() { 151 void Top::InitializeThreadLocal() {
130 thread_local_.Initialize(); 152 thread_local()->Initialize();
131 clear_pending_exception(); 153 clear_pending_exception();
132 clear_pending_message(); 154 clear_pending_message();
133 clear_scheduled_exception(); 155 clear_scheduled_exception();
134 } 156 }
135 157
136 158
137 // Create a dummy thread that will wait forever on a semaphore. The only 159 // Create a dummy thread that will wait forever on a semaphore. The only
138 // purpose for this thread is to have some stack area to save essential data 160 // purpose for this thread is to have some stack area to save essential data
139 // into for use by a stacks only core dump (aka minidump). 161 // into for use by a stacks only core dump (aka minidump).
140 class PreallocatedMemoryThread: public Thread { 162 class PreallocatedMemoryThread: public Thread {
141 public: 163 public:
142 PreallocatedMemoryThread() : keep_running_(true) { 164 char* data() {
143 wait_for_ever_semaphore_ = OS::CreateSemaphore(0);
144 data_ready_semaphore_ = OS::CreateSemaphore(0);
145 }
146
147 // When the thread starts running it will allocate a fixed number of bytes
148 // on the stack and publish the location of this memory for others to use.
149 void Run() {
150 EmbeddedVector<char, 15 * 1024> local_buffer;
151
152 // Initialize the buffer with a known good value.
153 OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
154 local_buffer.length());
155
156 // Publish the local buffer and signal its availability.
157 data_ = local_buffer.start();
158 length_ = local_buffer.length();
159 data_ready_semaphore_->Signal();
160
161 while (keep_running_) {
162 // This thread will wait here until the end of time.
163 wait_for_ever_semaphore_->Wait();
164 }
165
166 // Make sure we access the buffer after the wait to remove all possibility
167 // of it being optimized away.
168 OS::StrNCpy(local_buffer, "PreallocatedMemoryThread shutting down.\n",
169 local_buffer.length());
170 }
171
172 static char* data() {
173 if (data_ready_semaphore_ != NULL) { 165 if (data_ready_semaphore_ != NULL) {
174 // Initial access is guarded until the data has been published. 166 // Initial access is guarded until the data has been published.
175 data_ready_semaphore_->Wait(); 167 data_ready_semaphore_->Wait();
176 delete data_ready_semaphore_; 168 delete data_ready_semaphore_;
177 data_ready_semaphore_ = NULL; 169 data_ready_semaphore_ = NULL;
178 } 170 }
179 return data_; 171 return data_;
180 } 172 }
181 173
182 static unsigned length() { 174 unsigned length() {
183 if (data_ready_semaphore_ != NULL) { 175 if (data_ready_semaphore_ != NULL) {
184 // Initial access is guarded until the data has been published. 176 // Initial access is guarded until the data has been published.
185 data_ready_semaphore_->Wait(); 177 data_ready_semaphore_->Wait();
186 delete data_ready_semaphore_; 178 delete data_ready_semaphore_;
187 data_ready_semaphore_ = NULL; 179 data_ready_semaphore_ = NULL;
188 } 180 }
189 return length_; 181 return length_;
190 } 182 }
191 183
192 static void StartThread() {
193 if (the_thread_ != NULL) return;
194
195 the_thread_ = new PreallocatedMemoryThread();
196 the_thread_->Start();
197 }
198
199 // Stop the PreallocatedMemoryThread and release its resources. 184 // Stop the PreallocatedMemoryThread and release its resources.
200 static void StopThread() { 185 void StopThread() {
201 if (the_thread_ == NULL) return; 186 keep_running_ = false;
202
203 the_thread_->keep_running_ = false;
204 wait_for_ever_semaphore_->Signal(); 187 wait_for_ever_semaphore_->Signal();
205 188
206 // Wait for the thread to terminate. 189 // Wait for the thread to terminate.
207 the_thread_->Join(); 190 Join();
208 191
209 if (data_ready_semaphore_ != NULL) { 192 if (data_ready_semaphore_ != NULL) {
210 delete data_ready_semaphore_; 193 delete data_ready_semaphore_;
211 data_ready_semaphore_ = NULL; 194 data_ready_semaphore_ = NULL;
212 } 195 }
213 196
214 delete wait_for_ever_semaphore_; 197 delete wait_for_ever_semaphore_;
215 wait_for_ever_semaphore_ = NULL; 198 wait_for_ever_semaphore_ = NULL;
216
217 // Done with the thread entirely.
218 delete the_thread_;
219 the_thread_ = NULL;
220 } 199 }
221 200
201 protected:
202 // When the thread starts running it will allocate a fixed number of bytes
203 // on the stack and publish the location of this memory for others to use.
204 void Run() {
205 EmbeddedVector<char, 15 * 1024> local_buffer;
206
207 // Initialize the buffer with a known good value.
208 OS::StrNCpy(local_buffer, "Trace data was not generated.\n",
209 local_buffer.length());
210
211 // Publish the local buffer and signal its availability.
212 data_ = local_buffer.start();
213 length_ = local_buffer.length();
214 data_ready_semaphore_->Signal();
215
216 while (keep_running_) {
217 // This thread will wait here until the end of time.
218 wait_for_ever_semaphore_->Wait();
219 }
220
221 // Make sure we access the buffer after the wait to remove all possibility
222 // of it being optimized away.
223 OS::StrNCpy(local_buffer, "PreallocatedMemoryThread shutting down.\n",
224 local_buffer.length());
225 }
226
227
222 private: 228 private:
229 PreallocatedMemoryThread()
230 : keep_running_(true),
231 wait_for_ever_semaphore_(OS::CreateSemaphore(0)),
232 data_ready_semaphore_(OS::CreateSemaphore(0)),
233 data_(NULL),
234 length_(0) {
235 }
236
223 // Used to make sure that the thread keeps looping even for spurious wakeups. 237 // Used to make sure that the thread keeps looping even for spurious wakeups.
224 bool keep_running_; 238 bool keep_running_;
225 239
226 // The preallocated memory thread singleton.
227 static PreallocatedMemoryThread* the_thread_;
228 // This semaphore is used by the PreallocatedMemoryThread to wait for ever. 240 // This semaphore is used by the PreallocatedMemoryThread to wait for ever.
229 static Semaphore* wait_for_ever_semaphore_; 241 Semaphore* wait_for_ever_semaphore_;
230 // Semaphore to signal that the data has been initialized. 242 // Semaphore to signal that the data has been initialized.
231 static Semaphore* data_ready_semaphore_; 243 Semaphore* data_ready_semaphore_;
232 244
233 // Location and size of the preallocated memory block. 245 // Location and size of the preallocated memory block.
234 static char* data_; 246 char* data_;
235 static unsigned length_; 247 unsigned length_;
248
249 friend class TopState;
236 250
237 DISALLOW_COPY_AND_ASSIGN(PreallocatedMemoryThread); 251 DISALLOW_COPY_AND_ASSIGN(PreallocatedMemoryThread);
238 }; 252 };
239 253
240 PreallocatedMemoryThread* PreallocatedMemoryThread::the_thread_ = NULL;
241 Semaphore* PreallocatedMemoryThread::wait_for_ever_semaphore_ = NULL;
242 Semaphore* PreallocatedMemoryThread::data_ready_semaphore_ = NULL;
243 char* PreallocatedMemoryThread::data_ = NULL;
244 unsigned PreallocatedMemoryThread::length_ = 0;
245 254
246 static bool initialized = false; 255 void TopState::PreallocatedMemoryThreadStart() {
256 if (preallocated_memory_thread_ != NULL) return;
257 preallocated_memory_thread_ = new PreallocatedMemoryThread();
258 preallocated_memory_thread_->Start();
259 }
260
261
262 void TopState::PreallocatedMemoryThreadStop() {
263 if (preallocated_memory_thread_ == NULL) return;
264 preallocated_memory_thread_->StopThread();
265 // Done with the thread entirely.
266 delete preallocated_memory_thread_;
267 preallocated_memory_thread_ = NULL;
268 }
269
247 270
248 void Top::Initialize() { 271 void Top::Initialize() {
249 CHECK(!initialized); 272 CHECK(!top_state.initialized_);
250 273
251 InitializeThreadLocal(); 274 InitializeThreadLocal();
252 275
253 // Only preallocate on the first initialization. 276 // Only preallocate on the first initialization.
254 if (FLAG_preallocate_message_memory && (preallocated_message_space == NULL)) { 277 if (FLAG_preallocate_message_memory &&
278 (top_state.preallocated_message_space_ == NULL)) {
255 // Start the thread which will set aside some memory. 279 // Start the thread which will set aside some memory.
256 PreallocatedMemoryThread::StartThread(); 280 top_state.PreallocatedMemoryThreadStart();
257 preallocated_message_space = 281 top_state.preallocated_message_space_ =
258 new NoAllocationStringAllocator(PreallocatedMemoryThread::data(), 282 new NoAllocationStringAllocator(
259 PreallocatedMemoryThread::length()); 283 top_state.preallocated_memory_thread_->data(),
260 PreallocatedStorage::Init(PreallocatedMemoryThread::length() / 4); 284 top_state.preallocated_memory_thread_->length());
285 PreallocatedStorage::Init(
286 top_state.preallocated_memory_thread_->length() / 4);
261 } 287 }
262 initialized = true; 288 top_state.initialized_ = true;
263 } 289 }
264 290
265 291
266 void Top::TearDown() { 292 void Top::TearDown() {
267 if (initialized) { 293 if (top_state.initialized_) {
268 // Remove the external reference to the preallocated stack memory. 294 // Remove the external reference to the preallocated stack memory.
269 if (preallocated_message_space != NULL) { 295 if (top_state.preallocated_message_space_ != NULL) {
270 delete preallocated_message_space; 296 delete top_state.preallocated_message_space_;
271 preallocated_message_space = NULL; 297 top_state.preallocated_message_space_ = NULL;
272 } 298 }
273 299
274 PreallocatedMemoryThread::StopThread(); 300 top_state.PreallocatedMemoryThreadStop();
275 initialized = false; 301 top_state.initialized_ = false;
276 } 302 }
277 } 303 }
278 304
279 305
280 void Top::RegisterTryCatchHandler(v8::TryCatch* that) { 306 void Top::RegisterTryCatchHandler(v8::TryCatch* that) {
281 // The ARM simulator has a separate JS stack. We therefore register 307 // The ARM simulator has a separate JS stack. We therefore register
282 // the C++ try catch handler with the simulator and get back an 308 // the C++ try catch handler with the simulator and get back an
283 // address that can be used for comparisons with addresses into the 309 // address that can be used for comparisons with addresses into the
284 // JS stack. When running without the simulator, the address 310 // JS stack. When running without the simulator, the address
285 // returned will be the address of the C++ try catch handler itself. 311 // returned will be the address of the C++ try catch handler itself.
286 Address address = reinterpret_cast<Address>( 312 Address address = reinterpret_cast<Address>(
287 SimulatorStack::RegisterCTryCatch(reinterpret_cast<uintptr_t>(that))); 313 SimulatorStack::RegisterCTryCatch(reinterpret_cast<uintptr_t>(that)));
288 thread_local_.set_try_catch_handler_address(address); 314 thread_local()->set_try_catch_handler_address(address);
289 } 315 }
290 316
291 317
292 void Top::UnregisterTryCatchHandler(v8::TryCatch* that) { 318 void Top::UnregisterTryCatchHandler(v8::TryCatch* that) {
293 ASSERT(thread_local_.TryCatchHandler() == that); 319 ASSERT(thread_local()->TryCatchHandler() == that);
294 thread_local_.set_try_catch_handler_address( 320 thread_local()->set_try_catch_handler_address(
295 reinterpret_cast<Address>(that->next_)); 321 reinterpret_cast<Address>(that->next_));
296 thread_local_.catcher_ = NULL; 322 thread_local()->catcher_ = NULL;
297 SimulatorStack::UnregisterCTryCatch(); 323 SimulatorStack::UnregisterCTryCatch();
298 } 324 }
299 325
300 326
301 void Top::MarkCompactPrologue(bool is_compacting) { 327 void Top::MarkCompactPrologue(bool is_compacting) {
302 MarkCompactPrologue(is_compacting, &thread_local_); 328 MarkCompactPrologue(is_compacting, thread_local());
303 } 329 }
304 330
305 331
306 void Top::MarkCompactPrologue(bool is_compacting, char* data) { 332 void Top::MarkCompactPrologue(bool is_compacting, char* data) {
307 MarkCompactPrologue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data)); 333 MarkCompactPrologue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
308 } 334 }
309 335
310 336
311 void Top::MarkCompactPrologue(bool is_compacting, ThreadLocalTop* thread) { 337 void Top::MarkCompactPrologue(bool is_compacting, ThreadLocalTop* thread) {
312 if (is_compacting) { 338 if (is_compacting) {
313 StackFrame::CookFramesForThread(thread); 339 StackFrame::CookFramesForThread(thread);
314 } 340 }
315 } 341 }
316 342
317 343
318 void Top::MarkCompactEpilogue(bool is_compacting, char* data) { 344 void Top::MarkCompactEpilogue(bool is_compacting, char* data) {
319 MarkCompactEpilogue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data)); 345 MarkCompactEpilogue(is_compacting, reinterpret_cast<ThreadLocalTop*>(data));
320 } 346 }
321 347
322 348
323 void Top::MarkCompactEpilogue(bool is_compacting) { 349 void Top::MarkCompactEpilogue(bool is_compacting) {
324 MarkCompactEpilogue(is_compacting, &thread_local_); 350 MarkCompactEpilogue(is_compacting, thread_local());
325 } 351 }
326 352
327 353
328 void Top::MarkCompactEpilogue(bool is_compacting, ThreadLocalTop* thread) { 354 void Top::MarkCompactEpilogue(bool is_compacting, ThreadLocalTop* thread) {
329 if (is_compacting) { 355 if (is_compacting) {
330 StackFrame::UncookFramesForThread(thread); 356 StackFrame::UncookFramesForThread(thread);
331 } 357 }
332 } 358 }
333 359
334 360
335 static int stack_trace_nesting_level = 0;
336 static StringStream* incomplete_message = NULL;
337
338
339 Handle<String> Top::StackTraceString() { 361 Handle<String> Top::StackTraceString() {
340 if (stack_trace_nesting_level == 0) { 362 if (top_state.stack_trace_nesting_level_ == 0) {
341 stack_trace_nesting_level++; 363 top_state.stack_trace_nesting_level_++;
342 HeapStringAllocator allocator; 364 HeapStringAllocator allocator;
343 StringStream::ClearMentionedObjectCache(); 365 StringStream::ClearMentionedObjectCache();
344 StringStream accumulator(&allocator); 366 StringStream accumulator(&allocator);
345 incomplete_message = &accumulator; 367 top_state.incomplete_message_ = &accumulator;
346 PrintStack(&accumulator); 368 PrintStack(&accumulator);
347 Handle<String> stack_trace = accumulator.ToString(); 369 Handle<String> stack_trace = accumulator.ToString();
348 incomplete_message = NULL; 370 top_state.incomplete_message_ = NULL;
349 stack_trace_nesting_level = 0; 371 top_state.stack_trace_nesting_level_ = 0;
350 return stack_trace; 372 return stack_trace;
351 } else if (stack_trace_nesting_level == 1) { 373 } else if (top_state.stack_trace_nesting_level_ == 1) {
352 stack_trace_nesting_level++; 374 top_state.stack_trace_nesting_level_++;
353 OS::PrintError( 375 OS::PrintError(
354 "\n\nAttempt to print stack while printing stack (double fault)\n"); 376 "\n\nAttempt to print stack while printing stack (double fault)\n");
355 OS::PrintError( 377 OS::PrintError(
356 "If you are lucky you may find a partial stack dump on stdout.\n\n"); 378 "If you are lucky you may find a partial stack dump on stdout.\n\n");
357 incomplete_message->OutputToStdOut(); 379 top_state.incomplete_message_->OutputToStdOut();
358 return Factory::empty_symbol(); 380 return Factory::empty_symbol();
359 } else { 381 } else {
360 OS::Abort(); 382 OS::Abort();
361 // Unreachable 383 // Unreachable
362 return Factory::empty_symbol(); 384 return Factory::empty_symbol();
363 } 385 }
364 } 386 }
365 387
366 388
367 Local<StackTrace> Top::CaptureCurrentStackTrace( 389 Local<StackTrace> Top::CaptureCurrentStackTrace(
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 frames_seen++; 462 frames_seen++;
441 it.Advance(); 463 it.Advance();
442 } 464 }
443 465
444 stack_trace->set_length(Smi::FromInt(frames_seen)); 466 stack_trace->set_length(Smi::FromInt(frames_seen));
445 return scope.Close(Utils::StackTraceToLocal(stack_trace)); 467 return scope.Close(Utils::StackTraceToLocal(stack_trace));
446 } 468 }
447 469
448 470
449 void Top::PrintStack() { 471 void Top::PrintStack() {
450 if (stack_trace_nesting_level == 0) { 472 if (top_state.stack_trace_nesting_level_ == 0) {
451 stack_trace_nesting_level++; 473 top_state.stack_trace_nesting_level_++;
452 474
453 StringAllocator* allocator; 475 StringAllocator* allocator;
454 if (preallocated_message_space == NULL) { 476 if (top_state.preallocated_message_space_ == NULL) {
455 allocator = new HeapStringAllocator(); 477 allocator = new HeapStringAllocator();
456 } else { 478 } else {
457 allocator = preallocated_message_space; 479 allocator = top_state.preallocated_message_space_;
458 } 480 }
459 481
460 NativeAllocationChecker allocation_checker( 482 NativeAllocationChecker allocation_checker(
461 !FLAG_preallocate_message_memory ? 483 !FLAG_preallocate_message_memory ?
462 NativeAllocationChecker::ALLOW : 484 NativeAllocationChecker::ALLOW :
463 NativeAllocationChecker::DISALLOW); 485 NativeAllocationChecker::DISALLOW);
464 486
465 StringStream::ClearMentionedObjectCache(); 487 StringStream::ClearMentionedObjectCache();
466 StringStream accumulator(allocator); 488 StringStream accumulator(allocator);
467 incomplete_message = &accumulator; 489 top_state.incomplete_message_ = &accumulator;
468 PrintStack(&accumulator); 490 PrintStack(&accumulator);
469 accumulator.OutputToStdOut(); 491 accumulator.OutputToStdOut();
470 accumulator.Log(); 492 accumulator.Log();
471 incomplete_message = NULL; 493 top_state.incomplete_message_ = NULL;
472 stack_trace_nesting_level = 0; 494 top_state.stack_trace_nesting_level_ = 0;
473 if (preallocated_message_space == NULL) { 495 if (top_state.preallocated_message_space_ == NULL) {
474 // Remove the HeapStringAllocator created above. 496 // Remove the HeapStringAllocator created above.
475 delete allocator; 497 delete allocator;
476 } 498 }
477 } else if (stack_trace_nesting_level == 1) { 499 } else if (top_state.stack_trace_nesting_level_ == 1) {
478 stack_trace_nesting_level++; 500 top_state.stack_trace_nesting_level_++;
479 OS::PrintError( 501 OS::PrintError(
480 "\n\nAttempt to print stack while printing stack (double fault)\n"); 502 "\n\nAttempt to print stack while printing stack (double fault)\n");
481 OS::PrintError( 503 OS::PrintError(
482 "If you are lucky you may find a partial stack dump on stdout.\n\n"); 504 "If you are lucky you may find a partial stack dump on stdout.\n\n");
483 incomplete_message->OutputToStdOut(); 505 top_state.incomplete_message_->OutputToStdOut();
484 } 506 }
485 } 507 }
486 508
487 509
488 static void PrintFrames(StringStream* accumulator, 510 static void PrintFrames(StringStream* accumulator,
489 StackFrame::PrintMode mode) { 511 StackFrame::PrintMode mode) {
490 StackFrameIterator it; 512 StackFrameIterator it;
491 for (int i = 0; !it.done(); it.Advance()) { 513 for (int i = 0; !it.done(); it.Advance()) {
492 it.frame()->Print(accumulator, mode, i++); 514 it.frame()->Print(accumulator, mode, i++);
493 } 515 }
494 } 516 }
495 517
496 518
497 void Top::PrintStack(StringStream* accumulator) { 519 void Top::PrintStack(StringStream* accumulator) {
498 // The MentionedObjectCache is not GC-proof at the moment. 520 // The MentionedObjectCache is not GC-proof at the moment.
499 AssertNoAllocation nogc; 521 AssertNoAllocation nogc;
500 ASSERT(StringStream::IsMentionedObjectCacheClear()); 522 ASSERT(StringStream::IsMentionedObjectCacheClear());
501 523
502 // Avoid printing anything if there are no frames. 524 // Avoid printing anything if there are no frames.
503 if (c_entry_fp(GetCurrentThread()) == 0) return; 525 if (c_entry_fp(thread_local()) == 0) return;
504 526
505 accumulator->Add( 527 accumulator->Add(
506 "\n==== Stack trace ============================================\n\n"); 528 "\n==== Stack trace ============================================\n\n");
507 PrintFrames(accumulator, StackFrame::OVERVIEW); 529 PrintFrames(accumulator, StackFrame::OVERVIEW);
508 530
509 accumulator->Add( 531 accumulator->Add(
510 "\n==== Details ================================================\n\n"); 532 "\n==== Details ================================================\n\n");
511 PrintFrames(accumulator, StackFrame::DETAILS); 533 PrintFrames(accumulator, StackFrame::DETAILS);
512 534
513 accumulator->PrintMentionedObjectCache(); 535 accumulator->PrintMentionedObjectCache();
514 accumulator->Add("=====================\n\n"); 536 accumulator->Add("=====================\n\n");
515 } 537 }
516 538
517 539
518 void Top::SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback) { 540 void Top::SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback) {
519 ASSERT(thread_local_.failed_access_check_callback_ == NULL); 541 ASSERT(thread_local()->failed_access_check_callback_ == NULL);
520 thread_local_.failed_access_check_callback_ = callback; 542 thread_local()->failed_access_check_callback_ = callback;
521 } 543 }
522 544
523 545
524 void Top::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) { 546 void Top::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) {
525 if (!thread_local_.failed_access_check_callback_) return; 547 if (!thread_local()->failed_access_check_callback_) return;
526 548
527 ASSERT(receiver->IsAccessCheckNeeded()); 549 ASSERT(receiver->IsAccessCheckNeeded());
528 ASSERT(Top::context()); 550 ASSERT(Top::context());
529 // The callers of this method are not expecting a GC. 551 // The callers of this method are not expecting a GC.
530 AssertNoAllocation no_gc; 552 AssertNoAllocation no_gc;
531 553
532 // Get the data object from access check info. 554 // Get the data object from access check info.
533 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); 555 JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
534 if (!constructor->shared()->IsApiFunction()) return; 556 if (!constructor->shared()->IsApiFunction()) return;
535 Object* data_obj = 557 Object* data_obj =
536 constructor->shared()->get_api_func_data()->access_check_info(); 558 constructor->shared()->get_api_func_data()->access_check_info();
537 if (data_obj == HEAP->undefined_value()) return; 559 if (data_obj == HEAP->undefined_value()) return;
538 560
539 HandleScope scope; 561 HandleScope scope;
540 Handle<JSObject> receiver_handle(receiver); 562 Handle<JSObject> receiver_handle(receiver);
541 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data()); 563 Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());
542 thread_local_.failed_access_check_callback_( 564 thread_local()->failed_access_check_callback_(
543 v8::Utils::ToLocal(receiver_handle), 565 v8::Utils::ToLocal(receiver_handle),
544 type, 566 type,
545 v8::Utils::ToLocal(data)); 567 v8::Utils::ToLocal(data));
546 } 568 }
547 569
548 570
549 enum MayAccessDecision { 571 enum MayAccessDecision {
550 YES, NO, UNKNOWN 572 YES, NO, UNKNOWN
551 }; 573 };
552 574
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 732
711 Failure* Top::ThrowIllegalOperation() { 733 Failure* Top::ThrowIllegalOperation() {
712 return Throw(HEAP->illegal_access_symbol()); 734 return Throw(HEAP->illegal_access_symbol());
713 } 735 }
714 736
715 737
716 void Top::ScheduleThrow(Object* exception) { 738 void Top::ScheduleThrow(Object* exception) {
717 // When scheduling a throw we first throw the exception to get the 739 // When scheduling a throw we first throw the exception to get the
718 // error reporting if it is uncaught before rescheduling it. 740 // error reporting if it is uncaught before rescheduling it.
719 Throw(exception); 741 Throw(exception);
720 thread_local_.scheduled_exception_ = pending_exception(); 742 thread_local()->scheduled_exception_ = pending_exception();
721 thread_local_.external_caught_exception_ = false; 743 thread_local()->external_caught_exception_ = false;
722 clear_pending_exception(); 744 clear_pending_exception();
723 } 745 }
724 746
725 747
726 Object* Top::PromoteScheduledException() { 748 Object* Top::PromoteScheduledException() {
727 Object* thrown = scheduled_exception(); 749 Object* thrown = scheduled_exception();
728 clear_scheduled_exception(); 750 clear_scheduled_exception();
729 // Re-throw the exception to avoid getting repeated error reporting. 751 // Re-throw the exception to avoid getting repeated error reporting.
730 return ReThrow(thrown); 752 return ReThrow(thrown);
731 } 753 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 } 815 }
794 // Report the uncaught exception. 816 // Report the uncaught exception.
795 MessageHandler::ReportMessage(location, message); 817 MessageHandler::ReportMessage(location, message);
796 } 818 }
797 819
798 820
799 bool Top::ShouldReturnException(bool* is_caught_externally, 821 bool Top::ShouldReturnException(bool* is_caught_externally,
800 bool catchable_by_javascript) { 822 bool catchable_by_javascript) {
801 // Find the top-most try-catch handler. 823 // Find the top-most try-catch handler.
802 StackHandler* handler = 824 StackHandler* handler =
803 StackHandler::FromAddress(Top::handler(Top::GetCurrentThread())); 825 StackHandler::FromAddress(Top::handler(thread_local()));
804 while (handler != NULL && !handler->is_try_catch()) { 826 while (handler != NULL && !handler->is_try_catch()) {
805 handler = handler->next(); 827 handler = handler->next();
806 } 828 }
807 829
808 // Get the address of the external handler so we can compare the address to 830 // Get the address of the external handler so we can compare the address to
809 // determine which one is closer to the top of the stack. 831 // determine which one is closer to the top of the stack.
810 Address external_handler_address = thread_local_.try_catch_handler_address(); 832 Address external_handler_address =
833 thread_local()->try_catch_handler_address();
811 834
812 // The exception has been externally caught if and only if there is 835 // The exception has been externally caught if and only if there is
813 // an external handler which is on top of the top-most try-catch 836 // an external handler which is on top of the top-most try-catch
814 // handler. 837 // handler.
815 *is_caught_externally = external_handler_address != NULL && 838 *is_caught_externally = external_handler_address != NULL &&
816 (handler == NULL || handler->address() > external_handler_address || 839 (handler == NULL || handler->address() > external_handler_address ||
817 !catchable_by_javascript); 840 !catchable_by_javascript);
818 841
819 if (*is_caught_externally) { 842 if (*is_caught_externally) {
820 // Only report the exception if the external handler is verbose. 843 // Only report the exception if the external handler is verbose.
821 return thread_local_.TryCatchHandler()->is_verbose_; 844 return thread_local()->TryCatchHandler()->is_verbose_;
822 } else { 845 } else {
823 // Report the exception if it isn't caught by JavaScript code. 846 // Report the exception if it isn't caught by JavaScript code.
824 return handler == NULL; 847 return handler == NULL;
825 } 848 }
826 } 849 }
827 850
828 851
829 void Top::DoThrow(Object* exception, 852 void Top::DoThrow(Object* exception,
830 MessageLocation* location, 853 MessageLocation* location,
831 const char* message) { 854 const char* message) {
(...skipping 16 matching lines...) Expand all
848 if (catchable_by_javascript) { 871 if (catchable_by_javascript) {
849 Debugger::OnException(exception_handle, report_exception); 872 Debugger::OnException(exception_handle, report_exception);
850 } 873 }
851 #endif 874 #endif
852 875
853 // Generate the message. 876 // Generate the message.
854 Handle<Object> message_obj; 877 Handle<Object> message_obj;
855 MessageLocation potential_computed_location; 878 MessageLocation potential_computed_location;
856 bool try_catch_needs_message = 879 bool try_catch_needs_message =
857 is_caught_externally && 880 is_caught_externally &&
858 thread_local_.TryCatchHandler()->capture_message_; 881 thread_local()->TryCatchHandler()->capture_message_;
859 if (report_exception || try_catch_needs_message) { 882 if (report_exception || try_catch_needs_message) {
860 if (location == NULL) { 883 if (location == NULL) {
861 // If no location was specified we use a computed one instead 884 // If no location was specified we use a computed one instead
862 ComputeLocation(&potential_computed_location); 885 ComputeLocation(&potential_computed_location);
863 location = &potential_computed_location; 886 location = &potential_computed_location;
864 } 887 }
865 if (!Bootstrapper::IsActive()) { 888 if (!Bootstrapper::IsActive()) {
866 // It's not safe to try to make message objects or collect stack 889 // It's not safe to try to make message objects or collect stack
867 // traces while the bootstrapper is active since the infrastructure 890 // traces while the bootstrapper is active since the infrastructure
868 // may not have been properly initialized. 891 // may not have been properly initialized.
869 Handle<String> stack_trace; 892 Handle<String> stack_trace;
870 if (FLAG_trace_exception) stack_trace = StackTraceString(); 893 if (FLAG_trace_exception) stack_trace = StackTraceString();
871 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", 894 message_obj = MessageHandler::MakeMessageObject("uncaught_exception",
872 location, HandleVector<Object>(&exception_handle, 1), stack_trace); 895 location, HandleVector<Object>(&exception_handle, 1), stack_trace);
873 } 896 }
874 } 897 }
875 898
876 // Save the message for reporting if the the exception remains uncaught. 899 // Save the message for reporting if the the exception remains uncaught.
877 thread_local_.has_pending_message_ = report_exception; 900 thread_local()->has_pending_message_ = report_exception;
878 thread_local_.pending_message_ = message; 901 thread_local()->pending_message_ = message;
879 if (!message_obj.is_null()) { 902 if (!message_obj.is_null()) {
880 thread_local_.pending_message_obj_ = *message_obj; 903 thread_local()->pending_message_obj_ = *message_obj;
881 if (location != NULL) { 904 if (location != NULL) {
882 thread_local_.pending_message_script_ = *location->script(); 905 thread_local()->pending_message_script_ = *location->script();
883 thread_local_.pending_message_start_pos_ = location->start_pos(); 906 thread_local()->pending_message_start_pos_ = location->start_pos();
884 thread_local_.pending_message_end_pos_ = location->end_pos(); 907 thread_local()->pending_message_end_pos_ = location->end_pos();
885 } 908 }
886 } 909 }
887 910
888 if (is_caught_externally) { 911 if (is_caught_externally) {
889 thread_local_.catcher_ = thread_local_.TryCatchHandler(); 912 thread_local()->catcher_ = thread_local()->TryCatchHandler();
890 } 913 }
891 914
892 // NOTE: Notifying the debugger or generating the message 915 // NOTE: Notifying the debugger or generating the message
893 // may have caused new exceptions. For now, we just ignore 916 // may have caused new exceptions. For now, we just ignore
894 // that and set the pending exception to the original one. 917 // that and set the pending exception to the original one.
895 set_pending_exception(*exception_handle); 918 set_pending_exception(*exception_handle);
896 } 919 }
897 920
898 921
899 void Top::ReportPendingMessages() { 922 void Top::ReportPendingMessages() {
900 ASSERT(has_pending_exception()); 923 ASSERT(has_pending_exception());
901 setup_external_caught(); 924 setup_external_caught();
902 // If the pending exception is OutOfMemoryException set out_of_memory in 925 // If the pending exception is OutOfMemoryException set out_of_memory in
903 // the global context. Note: We have to mark the global context here 926 // the global context. Note: We have to mark the global context here
904 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to 927 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
905 // set it. 928 // set it.
906 bool external_caught = thread_local_.external_caught_exception_; 929 bool external_caught = thread_local()->external_caught_exception_;
907 HandleScope scope; 930 HandleScope scope;
908 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { 931 if (thread_local()->pending_exception_ == Failure::OutOfMemoryException()) {
909 context()->mark_out_of_memory(); 932 context()->mark_out_of_memory();
910 } else if (thread_local_.pending_exception_ == 933 } else if (thread_local()->pending_exception_ ==
911 HEAP->termination_exception()) { 934 HEAP->termination_exception()) {
912 if (external_caught) { 935 if (external_caught) {
913 thread_local_.TryCatchHandler()->can_continue_ = false; 936 thread_local()->TryCatchHandler()->can_continue_ = false;
914 thread_local_.TryCatchHandler()->exception_ = HEAP->null_value(); 937 thread_local()->TryCatchHandler()->exception_ = HEAP->null_value();
915 } 938 }
916 } else { 939 } else {
917 Handle<Object> exception(pending_exception()); 940 Handle<Object> exception(pending_exception());
918 thread_local_.external_caught_exception_ = false; 941 thread_local()->external_caught_exception_ = false;
919 if (external_caught) { 942 if (external_caught) {
920 thread_local_.TryCatchHandler()->can_continue_ = true; 943 thread_local()->TryCatchHandler()->can_continue_ = true;
921 thread_local_.TryCatchHandler()->exception_ = 944 thread_local()->TryCatchHandler()->exception_ =
922 thread_local_.pending_exception_; 945 thread_local()->pending_exception_;
923 if (!thread_local_.pending_message_obj_->IsTheHole()) { 946 if (!thread_local()->pending_message_obj_->IsTheHole()) {
924 try_catch_handler()->message_ = thread_local_.pending_message_obj_; 947 try_catch_handler()->message_ = thread_local()->pending_message_obj_;
925 } 948 }
926 } 949 }
927 if (thread_local_.has_pending_message_) { 950 if (thread_local()->has_pending_message_) {
928 thread_local_.has_pending_message_ = false; 951 thread_local()->has_pending_message_ = false;
929 if (thread_local_.pending_message_ != NULL) { 952 if (thread_local()->pending_message_ != NULL) {
930 MessageHandler::ReportMessage(thread_local_.pending_message_); 953 MessageHandler::ReportMessage(thread_local()->pending_message_);
931 } else if (!thread_local_.pending_message_obj_->IsTheHole()) { 954 } else if (!thread_local()->pending_message_obj_->IsTheHole()) {
932 Handle<Object> message_obj(thread_local_.pending_message_obj_); 955 Handle<Object> message_obj(thread_local()->pending_message_obj_);
933 if (thread_local_.pending_message_script_ != NULL) { 956 if (thread_local()->pending_message_script_ != NULL) {
934 Handle<Script> script(thread_local_.pending_message_script_); 957 Handle<Script> script(thread_local()->pending_message_script_);
935 int start_pos = thread_local_.pending_message_start_pos_; 958 int start_pos = thread_local()->pending_message_start_pos_;
936 int end_pos = thread_local_.pending_message_end_pos_; 959 int end_pos = thread_local()->pending_message_end_pos_;
937 MessageLocation location(script, start_pos, end_pos); 960 MessageLocation location(script, start_pos, end_pos);
938 MessageHandler::ReportMessage(&location, message_obj); 961 MessageHandler::ReportMessage(&location, message_obj);
939 } else { 962 } else {
940 MessageHandler::ReportMessage(NULL, message_obj); 963 MessageHandler::ReportMessage(NULL, message_obj);
941 } 964 }
942 } 965 }
943 } 966 }
944 thread_local_.external_caught_exception_ = external_caught; 967 thread_local()->external_caught_exception_ = external_caught;
945 set_pending_exception(*exception); 968 set_pending_exception(*exception);
946 } 969 }
947 clear_pending_message(); 970 clear_pending_message();
948 } 971 }
949 972
950 973
951 void Top::TraceException(bool flag) { 974 void Top::TraceException(bool flag) {
952 FLAG_trace_exception = flag; 975 FLAG_trace_exception = flag;
953 } 976 }
954 977
955 978
956 bool Top::OptionalRescheduleException(bool is_bottom_call) { 979 bool Top::OptionalRescheduleException(bool is_bottom_call) {
957 // Allways reschedule out of memory exceptions. 980 // Allways reschedule out of memory exceptions.
958 if (!is_out_of_memory()) { 981 if (!is_out_of_memory()) {
959 bool is_termination_exception = 982 bool is_termination_exception =
960 pending_exception() == HEAP->termination_exception(); 983 pending_exception() == HEAP->termination_exception();
961 984
962 // Do not reschedule the exception if this is the bottom call. 985 // Do not reschedule the exception if this is the bottom call.
963 bool clear_exception = is_bottom_call; 986 bool clear_exception = is_bottom_call;
964 987
965 if (is_termination_exception) { 988 if (is_termination_exception) {
966 if (is_bottom_call) { 989 if (is_bottom_call) {
967 thread_local_.external_caught_exception_ = false; 990 thread_local()->external_caught_exception_ = false;
968 clear_pending_exception(); 991 clear_pending_exception();
969 return false; 992 return false;
970 } 993 }
971 } else if (thread_local_.external_caught_exception_) { 994 } else if (thread_local()->external_caught_exception_) {
972 // If the exception is externally caught, clear it if there are no 995 // If the exception is externally caught, clear it if there are no
973 // JavaScript frames on the way to the C++ frame that has the 996 // JavaScript frames on the way to the C++ frame that has the
974 // external handler. 997 // external handler.
975 ASSERT(thread_local_.try_catch_handler_address() != NULL); 998 ASSERT(thread_local()->try_catch_handler_address() != NULL);
976 Address external_handler_address = 999 Address external_handler_address =
977 thread_local_.try_catch_handler_address(); 1000 thread_local()->try_catch_handler_address();
978 JavaScriptFrameIterator it; 1001 JavaScriptFrameIterator it;
979 if (it.done() || (it.frame()->sp() > external_handler_address)) { 1002 if (it.done() || (it.frame()->sp() > external_handler_address)) {
980 clear_exception = true; 1003 clear_exception = true;
981 } 1004 }
982 } 1005 }
983 1006
984 // Clear the exception if needed. 1007 // Clear the exception if needed.
985 if (clear_exception) { 1008 if (clear_exception) {
986 thread_local_.external_caught_exception_ = false; 1009 thread_local()->external_caught_exception_ = false;
987 clear_pending_exception(); 1010 clear_pending_exception();
988 return false; 1011 return false;
989 } 1012 }
990 } 1013 }
991 1014
992 // Reschedule the exception. 1015 // Reschedule the exception.
993 thread_local_.scheduled_exception_ = pending_exception(); 1016 thread_local()->scheduled_exception_ = pending_exception();
994 clear_pending_exception(); 1017 clear_pending_exception();
995 return true; 1018 return true;
996 } 1019 }
997 1020
998 1021
999 bool Top::is_out_of_memory() { 1022 bool Top::is_out_of_memory() {
1000 if (has_pending_exception()) { 1023 if (has_pending_exception()) {
1001 Object* e = pending_exception(); 1024 Object* e = pending_exception();
1002 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) { 1025 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1003 return true; 1026 return true;
1004 } 1027 }
1005 } 1028 }
1006 if (has_scheduled_exception()) { 1029 if (has_scheduled_exception()) {
1007 Object* e = scheduled_exception(); 1030 Object* e = scheduled_exception();
1008 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) { 1031 if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {
1009 return true; 1032 return true;
1010 } 1033 }
1011 } 1034 }
1012 return false; 1035 return false;
1013 } 1036 }
1014 1037
1015 1038
1016 Handle<Context> Top::global_context() { 1039 Handle<Context> Top::global_context() {
1017 GlobalObject* global = thread_local_.context_->global(); 1040 GlobalObject* global = thread_local()->context_->global();
1018 return Handle<Context>(global->global_context()); 1041 return Handle<Context>(global->global_context());
1019 } 1042 }
1020 1043
1021 1044
1022 Handle<Context> Top::GetCallingGlobalContext() { 1045 Handle<Context> Top::GetCallingGlobalContext() {
1023 JavaScriptFrameIterator it; 1046 JavaScriptFrameIterator it;
1024 #ifdef ENABLE_DEBUGGER_SUPPORT 1047 #ifdef ENABLE_DEBUGGER_SUPPORT
1025 if (Debug::InDebugger()) { 1048 if (Debug::InDebugger()) {
1026 while (!it.done()) { 1049 while (!it.done()) {
1027 JavaScriptFrame* frame = it.frame(); 1050 JavaScriptFrame* frame = it.frame();
1028 Context* context = Context::cast(frame->context()); 1051 Context* context = Context::cast(frame->context());
1029 if (context->global_context() == *Debug::debug_context()) { 1052 if (context->global_context() == *Debug::debug_context()) {
1030 it.Advance(); 1053 it.Advance();
1031 } else { 1054 } else {
1032 break; 1055 break;
1033 } 1056 }
1034 } 1057 }
1035 } 1058 }
1036 #endif // ENABLE_DEBUGGER_SUPPORT 1059 #endif // ENABLE_DEBUGGER_SUPPORT
1037 if (it.done()) return Handle<Context>::null(); 1060 if (it.done()) return Handle<Context>::null();
1038 JavaScriptFrame* frame = it.frame(); 1061 JavaScriptFrame* frame = it.frame();
1039 Context* context = Context::cast(frame->context()); 1062 Context* context = Context::cast(frame->context());
1040 return Handle<Context>(context->global_context()); 1063 return Handle<Context>(context->global_context());
1041 } 1064 }
1042 1065
1043 1066
1044 char* Top::ArchiveThread(char* to) { 1067 char* Top::ArchiveThread(char* to) {
1045 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(thread_local_)); 1068 memcpy(to, reinterpret_cast<char*>(thread_local()), sizeof(ThreadLocalTop));
1046 InitializeThreadLocal(); 1069 InitializeThreadLocal();
1047 return to + sizeof(thread_local_); 1070 return to + sizeof(ThreadLocalTop);
1048 } 1071 }
1049 1072
1050 1073
1051 char* Top::RestoreThread(char* from) { 1074 char* Top::RestoreThread(char* from) {
1052 memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(thread_local_)); 1075 memcpy(reinterpret_cast<char*>(thread_local()), from, sizeof(ThreadLocalTop));
1053 return from + sizeof(thread_local_); 1076 return from + sizeof(ThreadLocalTop);
1054 } 1077 }
1055 1078
1056 1079
1057 ExecutionAccess::ExecutionAccess() { 1080 ExecutionAccess::ExecutionAccess() {
1058 Isolate::Current()->break_access()->Lock(); 1081 Isolate::Current()->break_access()->Lock();
1059 } 1082 }
1060 1083
1061 1084
1062 ExecutionAccess::~ExecutionAccess() { 1085 ExecutionAccess::~ExecutionAccess() {
1063 Isolate::Current()->break_access()->Unlock(); 1086 Isolate::Current()->break_access()->Unlock();
1064 } 1087 }
1065 1088
1066 1089
1067 } } // namespace v8::internal 1090 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/top.h ('k') | test/cctest/test-log-stack-tracer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698