Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include "v8.h"
     29 
     30 #include "assembler.h"
     31 #include "isolate.h"
     32 #include "elements.h"
     33 #include "bootstrapper.h"
     34 #include "debug.h"
     35 #ifdef V8_USE_DEFAULT_PLATFORM
     36 #include "default-platform.h"
     37 #endif
     38 #include "deoptimizer.h"
     39 #include "frames.h"
     40 #include "heap-profiler.h"
     41 #include "hydrogen.h"
     42 #include "lithium-allocator.h"
     43 #include "objects.h"
     44 #include "once.h"
     45 #include "platform.h"
     46 #include "sampler.h"
     47 #include "runtime-profiler.h"
     48 #include "serialize.h"
     49 #include "store-buffer.h"
     50 
     51 namespace v8 {
     52 namespace internal {
     53 
     54 V8_DECLARE_ONCE(init_once);
     55 
     56 List<CallCompletedCallback>* V8::call_completed_callbacks_ = NULL;
     57 v8::ArrayBuffer::Allocator* V8::array_buffer_allocator_ = NULL;
     58 v8::Platform* V8::platform_ = NULL;
     59 
     60 
     61 bool V8::Initialize(Deserializer* des) {
     62   InitializeOncePerProcess();
     63 
     64   // The current thread may not yet had entered an isolate to run.
     65   // Note the Isolate::Current() may be non-null because for various
     66   // initialization purposes an initializing thread may be assigned an isolate
     67   // but not actually enter it.
     68   if (i::Isolate::CurrentPerIsolateThreadData() == NULL) {
     69     i::Isolate::EnterDefaultIsolate();
     70   }
     71 
     72   ASSERT(i::Isolate::CurrentPerIsolateThreadData() != NULL);
     73   ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id().Equals(
     74            i::ThreadId::Current()));
     75   ASSERT(i::Isolate::CurrentPerIsolateThreadData()->isolate() ==
     76          i::Isolate::Current());
     77 
     78   Isolate* isolate = Isolate::Current();
     79   if (isolate->IsDead()) return false;
     80   if (isolate->IsInitialized()) return true;
     81 
     82   return isolate->Init(des);
     83 }
     84 
     85 
     86 void V8::TearDown() {
     87   Isolate* isolate = Isolate::Current();
     88   ASSERT(isolate->IsDefaultIsolate());
     89   if (!isolate->IsInitialized()) return;
     90 
     91   // The isolate has to be torn down before clearing the LOperand
     92   // caches so that the optimizing compiler thread (if running)
     93   // doesn't see an inconsistent view of the lithium instructions.
     94   isolate->TearDown();
     95   delete isolate;
     96 
     97   ElementsAccessor::TearDown();
     98   LOperand::TearDownCaches();
     99   ExternalReference::TearDownMathExpData();
    100   RegisteredExtension::UnregisterAll();
    101   Isolate::GlobalTearDown();
    102 
    103   delete call_completed_callbacks_;
    104   call_completed_callbacks_ = NULL;
    105 
    106   Sampler::TearDown();
    107 
    108 #ifdef V8_USE_DEFAULT_PLATFORM
    109   DefaultPlatform* platform = static_cast<DefaultPlatform*>(platform_);
    110   platform_ = NULL;
    111   delete platform;
    112 #endif
    113 }
    114 
    115 
    116 void V8::SetReturnAddressLocationResolver(
    117       ReturnAddressLocationResolver resolver) {
    118   StackFrame::SetReturnAddressLocationResolver(resolver);
    119 }
    120 
    121 
    122 void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
    123   if (call_completed_callbacks_ == NULL) {  // Lazy init.
    124     call_completed_callbacks_ = new List<CallCompletedCallback>();
    125   }
    126   for (int i = 0; i < call_completed_callbacks_->length(); i++) {
    127     if (callback == call_completed_callbacks_->at(i)) return;
    128   }
    129   call_completed_callbacks_->Add(callback);
    130 }
    131 
    132 
    133 void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
    134   if (call_completed_callbacks_ == NULL) return;
    135   for (int i = 0; i < call_completed_callbacks_->length(); i++) {
    136     if (callback == call_completed_callbacks_->at(i)) {
    137       call_completed_callbacks_->Remove(i);
    138     }
    139   }
    140 }
    141 
    142 
    143 void V8::FireCallCompletedCallback(Isolate* isolate) {
    144   bool has_call_completed_callbacks = call_completed_callbacks_ != NULL;
    145   bool microtask_pending = isolate->microtask_pending();
    146   if (!has_call_completed_callbacks && !microtask_pending) return;
    147 
    148   HandleScopeImplementer* handle_scope_implementer =
    149       isolate->handle_scope_implementer();
    150   if (!handle_scope_implementer->CallDepthIsZero()) return;
    151   // Fire callbacks.  Increase call depth to prevent recursive callbacks.
    152   handle_scope_implementer->IncrementCallDepth();
    153   if (microtask_pending) Execution::RunMicrotasks(isolate);
    154   if (has_call_completed_callbacks) {
    155     for (int i = 0; i < call_completed_callbacks_->length(); i++) {
    156       call_completed_callbacks_->at(i)();
    157     }
    158   }
    159   handle_scope_implementer->DecrementCallDepth();
    160 }
    161 
    162 
    163 void V8::InitializeOncePerProcessImpl() {
    164   FlagList::EnforceFlagImplications();
    165   if (FLAG_stress_compaction) {
    166     FLAG_force_marking_deque_overflows = true;
    167     FLAG_gc_global = true;
    168     FLAG_max_new_space_size = (1 << (kPageSizeBits - 10)) * 2;
    169   }
    170 
    171 #ifdef V8_USE_DEFAULT_PLATFORM
    172   platform_ = new DefaultPlatform;
    173 #endif
    174   Sampler::SetUp();
    175   CPU::SetUp();
    176   OS::PostSetUp();
    177   ElementsAccessor::InitializeOncePerProcess();
    178   LOperand::SetUpCaches();
    179   SetUpJSCallerSavedCodeData();
    180   ExternalReference::SetUp();
    181   Bootstrapper::InitializeOncePerProcess();
    182 }
    183 
    184 
    185 void V8::InitializeOncePerProcess() {
    186   CallOnce(&init_once, &InitializeOncePerProcessImpl);
    187 }
    188 
    189 
    190 void V8::InitializePlatform(v8::Platform* platform) {
    191   ASSERT(!platform_);
    192   ASSERT(platform);
    193   platform_ = platform;
    194 }
    195 
    196 
    197 void V8::ShutdownPlatform() {
    198   ASSERT(platform_);
    199   platform_ = NULL;
    200 }
    201 
    202 
    203 v8::Platform* V8::GetCurrentPlatform() {
    204   ASSERT(platform_);
    205   return platform_;
    206 }
    207 
    208 } }  // namespace v8::internal
    209