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

Side by Side Diff: src/execution.cc

Issue 2715004: [Isolates]... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: Address comments/make StackGuard::ThreadLocal::Initialize/Clear side-effects visible 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
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 22 matching lines...) Expand all
33 #include "bootstrapper.h" 33 #include "bootstrapper.h"
34 #include "codegen-inl.h" 34 #include "codegen-inl.h"
35 #include "debug.h" 35 #include "debug.h"
36 #include "simulator.h" 36 #include "simulator.h"
37 #include "v8threads.h" 37 #include "v8threads.h"
38 38
39 namespace v8 { 39 namespace v8 {
40 namespace internal { 40 namespace internal {
41 41
42 42
43 StackGuard::StackGuard()
44 : isolate_(NULL),
45 stack_limit_key_(Thread::CreateThreadLocalKey()) {
46 thread_local_.Clear();
47 }
48
49
50 void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
51 ASSERT(isolate_ != NULL);
52 // Ignore attempts to interrupt when interrupts are postponed.
53 if (should_postpone_interrupts(lock)) return;
54 thread_local_.jslimit_ = kInterruptLimit;
55 thread_local_.climit_ = kInterruptLimit;
56 isolate_->heap()->SetStackLimits();
57 }
58
59
60 void StackGuard::reset_limits(const ExecutionAccess& lock) {
61 ASSERT(isolate_ != NULL);
62 thread_local_.jslimit_ = thread_local_.real_jslimit_;
63 thread_local_.climit_ = thread_local_.real_climit_;
64 isolate_->heap()->SetStackLimits();
65 }
66
67
43 static Handle<Object> Invoke(bool construct, 68 static Handle<Object> Invoke(bool construct,
44 Handle<JSFunction> func, 69 Handle<JSFunction> func,
45 Handle<Object> receiver, 70 Handle<Object> receiver,
46 int argc, 71 int argc,
47 Object*** args, 72 Object*** args,
48 bool* has_pending_exception) { 73 bool* has_pending_exception) {
49 // Entering JavaScript. 74 // Entering JavaScript.
50 VMState state(JS); 75 VMState state(JS);
51 76
52 // Placeholder for return value. 77 // Placeholder for return value.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 if (object->IsHeapObject() && 223 if (object->IsHeapObject() &&
199 HeapObject::cast(*object)->map()->has_instance_call_handler()) { 224 HeapObject::cast(*object)->map()->has_instance_call_handler()) {
200 return Handle<JSFunction>( 225 return Handle<JSFunction>(
201 Top::global_context()->call_as_constructor_delegate()); 226 Top::global_context()->call_as_constructor_delegate());
202 } 227 }
203 228
204 return Factory::undefined_value(); 229 return Factory::undefined_value();
205 } 230 }
206 231
207 232
208 // Static state for stack guards.
209 StackGuard::ThreadLocal StackGuard::thread_local_;
210
211
212 bool StackGuard::IsStackOverflow() { 233 bool StackGuard::IsStackOverflow() {
213 ExecutionAccess access; 234 ExecutionAccess access;
214 return (thread_local_.jslimit_ != kInterruptLimit && 235 return (thread_local_.jslimit_ != kInterruptLimit &&
215 thread_local_.climit_ != kInterruptLimit); 236 thread_local_.climit_ != kInterruptLimit);
216 } 237 }
217 238
218 239
219 void StackGuard::EnableInterrupts() { 240 void StackGuard::EnableInterrupts() {
220 ExecutionAccess access; 241 ExecutionAccess access;
221 if (has_pending_interrupts(access)) { 242 if (has_pending_interrupts(access)) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 337
317 void StackGuard::Continue(InterruptFlag after_what) { 338 void StackGuard::Continue(InterruptFlag after_what) {
318 ExecutionAccess access; 339 ExecutionAccess access;
319 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); 340 thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
320 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { 341 if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
321 reset_limits(access); 342 reset_limits(access);
322 } 343 }
323 } 344 }
324 345
325 346
326 int StackGuard::ArchiveSpacePerThread() {
327 return sizeof(ThreadLocal);
328 }
329
330
331 char* StackGuard::ArchiveStackGuard(char* to) { 347 char* StackGuard::ArchiveStackGuard(char* to) {
332 ExecutionAccess access; 348 ExecutionAccess access;
333 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 349 memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
334 ThreadLocal blank; 350 ThreadLocal blank;
Vitaly Repeshko 2010/06/09 21:22:38 Can we make its constructor call Clear()?
351 blank.Clear();
352
353 // Set the stack limits using the old thread_local_.
354 // TODO(isolates): This was the old semantics of constructing a ThreadLocal
355 // (as the ctor called SetStackLimits, which looked at the
356 // current thread_local_ from StackGuard)-- but is this
357 // really what was intended?
358 isolate_->heap()->SetStackLimits();
359
335 thread_local_ = blank; 360 thread_local_ = blank;
336 return to + sizeof(ThreadLocal); 361 return to + sizeof(ThreadLocal);
337 } 362 }
338 363
339 364
340 char* StackGuard::RestoreStackGuard(char* from) { 365 char* StackGuard::RestoreStackGuard(char* from) {
341 ExecutionAccess access; 366 ExecutionAccess access;
342 memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 367 memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
343 Heap::SetStackLimits(); 368 isolate_->heap()->SetStackLimits();
344 return from + sizeof(ThreadLocal); 369 return from + sizeof(ThreadLocal);
345 } 370 }
346 371
347 372
348 static internal::Thread::LocalStorageKey stack_limit_key = 373 static internal::Thread::LocalStorageKey stack_limit_key =
349 internal::Thread::CreateThreadLocalKey(); 374 internal::Thread::CreateThreadLocalKey();
350 375
351 376
352 void StackGuard::FreeThreadResources() { 377 void StackGuard::FreeThreadResources() {
353 Thread::SetThreadLocal( 378 Thread::SetThreadLocal(
354 stack_limit_key, 379 stack_limit_key,
355 reinterpret_cast<void*>(thread_local_.real_climit_)); 380 reinterpret_cast<void*>(thread_local_.real_climit_));
356 } 381 }
357 382
358 383
384 StackGuard::ThreadLocal::ThreadLocal() {
385 }
386
387
359 void StackGuard::ThreadLocal::Clear() { 388 void StackGuard::ThreadLocal::Clear() {
360 real_jslimit_ = kIllegalLimit; 389 real_jslimit_ = kIllegalLimit;
361 jslimit_ = kIllegalLimit; 390 jslimit_ = kIllegalLimit;
362 real_climit_ = kIllegalLimit; 391 real_climit_ = kIllegalLimit;
363 climit_ = kIllegalLimit; 392 climit_ = kIllegalLimit;
364 nesting_ = 0; 393 nesting_ = 0;
365 postpone_interrupts_nesting_ = 0; 394 postpone_interrupts_nesting_ = 0;
366 interrupt_flags_ = 0; 395 interrupt_flags_ = 0;
367 Heap::SetStackLimits();
368 } 396 }
369 397
370 398
371 void StackGuard::ThreadLocal::Initialize() { 399 bool StackGuard::ThreadLocal::Initialize() {
400 bool should_set_stack_limits = false;
372 if (real_climit_ == kIllegalLimit) { 401 if (real_climit_ == kIllegalLimit) {
373 // Takes the address of the limit variable in order to find out where 402 // Takes the address of the limit variable in order to find out where
374 // the top of stack is right now. 403 // the top of stack is right now.
375 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; 404 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
376 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); 405 ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
377 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); 406 real_jslimit_ = SimulatorStack::JsLimitFromCLimit(limit);
378 jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); 407 jslimit_ = SimulatorStack::JsLimitFromCLimit(limit);
379 real_climit_ = limit; 408 real_climit_ = limit;
380 climit_ = limit; 409 climit_ = limit;
381 Heap::SetStackLimits(); 410 should_set_stack_limits = true;
382 } 411 }
383 nesting_ = 0; 412 nesting_ = 0;
384 postpone_interrupts_nesting_ = 0; 413 postpone_interrupts_nesting_ = 0;
385 interrupt_flags_ = 0; 414 interrupt_flags_ = 0;
415 return should_set_stack_limits;
386 } 416 }
387 417
388 418
389 void StackGuard::ClearThread(const ExecutionAccess& lock) { 419 void StackGuard::ClearThread(const ExecutionAccess& lock) {
390 thread_local_.Clear(); 420 thread_local_.Clear();
421 isolate_->heap()->SetStackLimits();
391 } 422 }
392 423
393 424
394 void StackGuard::InitThread(const ExecutionAccess& lock) { 425 void StackGuard::InitThread(const ExecutionAccess& lock) {
395 thread_local_.Initialize(); 426 if (thread_local_.Initialize()) { isolate_->heap()->SetStackLimits(); }
Vitaly Repeshko 2010/06/09 21:22:38 nit: No {} for one-line ifs.
396 void* stored_limit = Thread::GetThreadLocal(stack_limit_key); 427 void* stored_limit = Thread::GetThreadLocal(stack_limit_key);
397 // You should hold the ExecutionAccess lock when you call this. 428 // You should hold the ExecutionAccess lock when you call this.
398 if (stored_limit != NULL) { 429 if (stored_limit != NULL) {
399 StackGuard::SetStackLimit(reinterpret_cast<intptr_t>(stored_limit)); 430 StackGuard::SetStackLimit(reinterpret_cast<intptr_t>(stored_limit));
400 } 431 }
401 } 432 }
402 433
403 434
404 // --- C a l l s t o n a t i v e s --- 435 // --- C a l l s t o n a t i v e s ---
405 436
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 bool caught_exception = false; 596 bool caught_exception = false;
566 Handle<Object> result = TryCall(Top::get_stack_trace_line_fun(), 597 Handle<Object> result = TryCall(Top::get_stack_trace_line_fun(),
567 Top::builtins(), argc, args, 598 Top::builtins(), argc, args,
568 &caught_exception); 599 &caught_exception);
569 if (caught_exception || !result->IsString()) return Factory::empty_symbol(); 600 if (caught_exception || !result->IsString()) return Factory::empty_symbol();
570 return Handle<String>::cast(result); 601 return Handle<String>::cast(result);
571 } 602 }
572 603
573 604
574 static Object* RuntimePreempt() { 605 static Object* RuntimePreempt() {
606 Isolate* isolate = Isolate::Current();
607
575 // Clear the preempt request flag. 608 // Clear the preempt request flag.
576 StackGuard::Continue(PREEMPT); 609 isolate->stack_guard()->Continue(PREEMPT);
577 610
578 ContextSwitcher::PreemptionReceived(); 611 ContextSwitcher::PreemptionReceived();
579 612
580 #ifdef ENABLE_DEBUGGER_SUPPORT 613 #ifdef ENABLE_DEBUGGER_SUPPORT
581 if (Debug::InDebugger()) { 614 if (Debug::InDebugger()) {
582 // If currently in the debugger don't do any actual preemption but record 615 // If currently in the debugger don't do any actual preemption but record
583 // that preemption occoured while in the debugger. 616 // that preemption occoured while in the debugger.
584 Debug::PreemptionWhileInDebugger(); 617 Debug::PreemptionWhileInDebugger();
585 } else { 618 } else {
586 // Perform preemption. 619 // Perform preemption.
587 v8::Unlocker unlocker; 620 v8::Unlocker unlocker;
588 Thread::YieldCPU(); 621 Thread::YieldCPU();
589 } 622 }
590 #else 623 #else
591 // Perform preemption. 624 // Perform preemption.
Vitaly Repeshko 2010/06/09 21:22:38 Unrelated to your change, but this looks like a ra
592 v8::Unlocker unlocker; 625 v8::Unlocker unlocker;
593 Thread::YieldCPU(); 626 Thread::YieldCPU();
594 #endif 627 #endif
595 628
596 return HEAP->undefined_value(); 629 return isolate->heap()->undefined_value();
597 } 630 }
598 631
599 632
600 #ifdef ENABLE_DEBUGGER_SUPPORT 633 #ifdef ENABLE_DEBUGGER_SUPPORT
601 Object* Execution::DebugBreakHelper() { 634 Object* Execution::DebugBreakHelper() {
635 Isolate* isolate = Isolate::Current();
636
602 // Just continue if breaks are disabled. 637 // Just continue if breaks are disabled.
603 if (Debug::disable_break()) { 638 if (Debug::disable_break()) {
604 return HEAP->undefined_value(); 639 return isolate->heap()->undefined_value();
605 } 640 }
606 641
607 // Ignore debug break during bootstrapping. 642 // Ignore debug break during bootstrapping.
608 if (Bootstrapper::IsActive()) { 643 if (Bootstrapper::IsActive()) {
609 return HEAP->undefined_value(); 644 return isolate->heap()->undefined_value();
610 } 645 }
611 646
612 { 647 {
613 JavaScriptFrameIterator it; 648 JavaScriptFrameIterator it;
614 ASSERT(!it.done()); 649 ASSERT(!it.done());
615 Object* fun = it.frame()->function(); 650 Object* fun = it.frame()->function();
616 if (fun && fun->IsJSFunction()) { 651 if (fun && fun->IsJSFunction()) {
617 // Don't stop in builtin functions. 652 // Don't stop in builtin functions.
618 if (JSFunction::cast(fun)->IsBuiltin()) { 653 if (JSFunction::cast(fun)->IsBuiltin()) {
619 return HEAP->undefined_value(); 654 return isolate->heap()->undefined_value();
620 } 655 }
621 GlobalObject* global = JSFunction::cast(fun)->context()->global(); 656 GlobalObject* global = JSFunction::cast(fun)->context()->global();
622 // Don't stop in debugger functions. 657 // Don't stop in debugger functions.
623 if (Debug::IsDebugGlobal(global)) { 658 if (Debug::IsDebugGlobal(global)) {
624 return HEAP->undefined_value(); 659 return isolate->heap()->undefined_value();
625 } 660 }
626 } 661 }
627 } 662 }
628 663
629 // Collect the break state before clearing the flags. 664 // Collect the break state before clearing the flags.
630 bool debug_command_only = 665 bool debug_command_only =
631 StackGuard::IsDebugCommand() && !StackGuard::IsDebugBreak(); 666 isolate->stack_guard()->IsDebugCommand() &&
667 !isolate->stack_guard()->IsDebugBreak();
632 668
633 // Clear the debug break request flag. 669 // Clear the debug break request flag.
634 StackGuard::Continue(DEBUGBREAK); 670 isolate->stack_guard()->Continue(DEBUGBREAK);
635 671
636 ProcessDebugMesssages(debug_command_only); 672 ProcessDebugMesssages(debug_command_only);
637 673
638 // Return to continue execution. 674 // Return to continue execution.
639 return HEAP->undefined_value(); 675 return isolate->heap()->undefined_value();
640 } 676 }
641 677
642 void Execution::ProcessDebugMesssages(bool debug_command_only) { 678 void Execution::ProcessDebugMesssages(bool debug_command_only) {
643 // Clear the debug command request flag. 679 // Clear the debug command request flag.
644 StackGuard::Continue(DEBUGCOMMAND); 680 Isolate::Current()->stack_guard()->Continue(DEBUGCOMMAND);
645 681
646 HandleScope scope; 682 HandleScope scope;
647 // Enter the debugger. Just continue if we fail to enter the debugger. 683 // Enter the debugger. Just continue if we fail to enter the debugger.
648 EnterDebugger debugger; 684 EnterDebugger debugger;
649 if (debugger.FailedToEnter()) { 685 if (debugger.FailedToEnter()) {
650 return; 686 return;
651 } 687 }
652 688
653 // Notify the debug event listeners. Indicate auto continue if the break was 689 // Notify the debug event listeners. Indicate auto continue if the break was
654 // a debug command break. 690 // a debug command break.
655 Debugger::OnDebugBreak(Factory::undefined_value(), debug_command_only); 691 Debugger::OnDebugBreak(Factory::undefined_value(), debug_command_only);
656 } 692 }
657 693
658 694
659 #endif 695 #endif
660 696
661 Object* Execution::HandleStackGuardInterrupt() { 697 Object* Execution::HandleStackGuardInterrupt() {
698 Isolate* isolate = Isolate::Current();
662 #ifdef ENABLE_DEBUGGER_SUPPORT 699 #ifdef ENABLE_DEBUGGER_SUPPORT
663 if (StackGuard::IsDebugBreak() || StackGuard::IsDebugCommand()) { 700 if (isolate->stack_guard()->IsDebugBreak() ||
701 isolate->stack_guard()->IsDebugCommand()) {
664 DebugBreakHelper(); 702 DebugBreakHelper();
665 } 703 }
666 #endif 704 #endif
667 if (StackGuard::IsPreempted()) RuntimePreempt(); 705 if (isolate->stack_guard()->IsPreempted()) RuntimePreempt();
668 if (StackGuard::IsTerminateExecution()) { 706 if (isolate->stack_guard()->IsTerminateExecution()) {
669 StackGuard::Continue(TERMINATE); 707 isolate->stack_guard()->Continue(TERMINATE);
670 return Top::TerminateExecution(); 708 return Top::TerminateExecution();
671 } 709 }
672 if (StackGuard::IsInterrupted()) { 710 if (isolate->stack_guard()->IsInterrupted()) {
673 // interrupt 711 // interrupt
674 StackGuard::Continue(INTERRUPT); 712 isolate->stack_guard()->Continue(INTERRUPT);
675 return Top::StackOverflow(); 713 return Top::StackOverflow();
676 } 714 }
677 return HEAP->undefined_value(); 715 return isolate->heap()->undefined_value();
678 } 716 }
679 717
680 // --- G C E x t e n s i o n --- 718 // --- G C E x t e n s i o n ---
681 719
682 const char* GCExtension::kSource = "native function gc();"; 720 const char* GCExtension::kSource = "native function gc();";
683 721
684 722
685 v8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunction( 723 v8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunction(
686 v8::Handle<v8::String> str) { 724 v8::Handle<v8::String> str) {
687 return v8::FunctionTemplate::New(GCExtension::GC); 725 return v8::FunctionTemplate::New(GCExtension::GC);
688 } 726 }
689 727
690 728
691 v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) { 729 v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) {
692 // All allocation spaces other than NEW_SPACE have the same effect. 730 // All allocation spaces other than NEW_SPACE have the same effect.
693 Heap::CollectAllGarbage(false); 731 Heap::CollectAllGarbage(false);
694 return v8::Undefined(); 732 return v8::Undefined();
695 } 733 }
696 734
697 735
698 static GCExtension kGCExtension; 736 static GCExtension kGCExtension;
699 v8::DeclareExtension kGCExtensionDeclaration(&kGCExtension); 737 v8::DeclareExtension kGCExtensionDeclaration(&kGCExtension);
700 738
701 } } // namespace v8::internal 739 } } // namespace v8::internal
OLDNEW
« src/execution.h ('K') | « src/execution.h ('k') | src/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698