v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
v8.cc
Go to the documentation of this file.
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 #include "deoptimizer.h"
36 #include "frames.h"
37 #include "heap-profiler.h"
38 #include "hydrogen.h"
39 #include "lithium-allocator.h"
40 #include "log.h"
41 #include "once.h"
42 #include "platform.h"
43 #include "runtime-profiler.h"
44 #include "serialize.h"
45 #include "store-buffer.h"
46 
47 namespace v8 {
48 namespace internal {
49 
50 V8_DECLARE_ONCE(init_once);
51 
52 bool V8::is_running_ = false;
53 bool V8::has_been_set_up_ = false;
54 bool V8::has_been_disposed_ = false;
55 bool V8::has_fatal_error_ = false;
56 bool V8::use_crankshaft_ = true;
57 List<CallCompletedCallback>* V8::call_completed_callbacks_ = NULL;
58 
59 static LazyMutex entropy_mutex = LAZY_MUTEX_INITIALIZER;
60 
61 static EntropySource entropy_source;
62 
63 
65  FlagList::EnforceFlagImplications();
66 
67  InitializeOncePerProcess();
68 
69  // The current thread may not yet had entered an isolate to run.
70  // Note the Isolate::Current() may be non-null because for various
71  // initialization purposes an initializing thread may be assigned an isolate
72  // but not actually enter it.
75  }
76 
78  ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id().Equals(
81  i::Isolate::Current());
82 
83  if (IsDead()) return false;
84 
85  Isolate* isolate = Isolate::Current();
86  if (isolate->IsInitialized()) return true;
87 
88  is_running_ = true;
89  has_been_set_up_ = true;
90  has_fatal_error_ = false;
91  has_been_disposed_ = false;
92 
93  return isolate->Init(des);
94 }
95 
96 
98  is_running_ = false;
99  has_fatal_error_ = true;
100 }
101 
102 
103 void V8::TearDown() {
104  Isolate* isolate = Isolate::Current();
105  ASSERT(isolate->IsDefaultIsolate());
106 
107  if (!has_been_set_up_ || has_been_disposed_) return;
108 
112 
113  isolate->TearDown();
114  delete isolate;
115 
116  is_running_ = false;
117  has_been_disposed_ = true;
118 
119  delete call_completed_callbacks_;
120  call_completed_callbacks_ = NULL;
121 
122  OS::TearDown();
123 }
124 
125 
126 static void seed_random(uint32_t* state) {
127  for (int i = 0; i < 2; ++i) {
128  if (FLAG_random_seed != 0) {
129  state[i] = FLAG_random_seed;
130  } else if (entropy_source != NULL) {
131  uint32_t val;
132  ScopedLock lock(entropy_mutex.Pointer());
133  entropy_source(reinterpret_cast<unsigned char*>(&val), sizeof(uint32_t));
134  state[i] = val;
135  } else {
136  state[i] = random();
137  }
138  }
139 }
140 
141 
142 // Random number generator using George Marsaglia's MWC algorithm.
143 static uint32_t random_base(uint32_t* state) {
144  // Initialize seed using the system random().
145  // No non-zero seed will ever become zero again.
146  if (state[0] == 0) seed_random(state);
147 
148  // Mix the bits. Never replaces state[i] with 0 if it is nonzero.
149  state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16);
150  state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16);
151 
152  return (state[0] << 14) + (state[1] & 0x3FFFF);
153 }
154 
155 
157  entropy_source = source;
158 }
159 
160 
163  StackFrame::SetReturnAddressLocationResolver(resolver);
164 }
165 
166 
167 // Used by JavaScript APIs
168 uint32_t V8::Random(Context* context) {
169  ASSERT(context->IsGlobalContext());
170  ByteArray* seed = context->random_seed();
171  return random_base(reinterpret_cast<uint32_t*>(seed->GetDataStartAddress()));
172 }
173 
174 
175 // Used internally by the JIT and memory allocator for security
176 // purposes. So, we keep a different state to prevent informations
177 // leaks that could be used in an exploit.
178 uint32_t V8::RandomPrivate(Isolate* isolate) {
179  ASSERT(isolate == Isolate::Current());
180  return random_base(isolate->private_random_seed());
181 }
182 
183 
184 bool V8::IdleNotification(int hint) {
185  // Returning true tells the caller that there is no need to call
186  // IdleNotification again.
187  if (!FLAG_use_idle_notification) return true;
188 
189  // Tell the heap that it may want to adjust.
190  return HEAP->IdleNotification(hint);
191 }
192 
193 
195  if (call_completed_callbacks_ == NULL) { // Lazy init.
196  call_completed_callbacks_ = new List<CallCompletedCallback>();
197  }
198  for (int i = 0; i < call_completed_callbacks_->length(); i++) {
199  if (callback == call_completed_callbacks_->at(i)) return;
200  }
201  call_completed_callbacks_->Add(callback);
202 }
203 
204 
206  if (call_completed_callbacks_ == NULL) return;
207  for (int i = 0; i < call_completed_callbacks_->length(); i++) {
208  if (callback == call_completed_callbacks_->at(i)) {
209  call_completed_callbacks_->Remove(i);
210  }
211  }
212 }
213 
214 
216  if (call_completed_callbacks_ == NULL) return;
217  HandleScopeImplementer* handle_scope_implementer =
218  isolate->handle_scope_implementer();
219  if (!handle_scope_implementer->CallDepthIsZero()) return;
220  // Fire callbacks. Increase call depth to prevent recursive callbacks.
221  handle_scope_implementer->IncrementCallDepth();
222  for (int i = 0; i < call_completed_callbacks_->length(); i++) {
223  call_completed_callbacks_->at(i)();
224  }
225  handle_scope_implementer->DecrementCallDepth();
226 }
227 
228 
229 // Use a union type to avoid type-aliasing optimizations in GCC.
230 typedef union {
231  double double_value;
232  uint64_t uint64_t_value;
234 
235 
237  Context* context) {
239  uint64_t random_bits = Random(context);
240  // Convert 32 random bits to 0.(32 random bits) in a double
241  // by computing:
242  // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
243  static const double binary_million = 1048576.0;
244  r.double_value = binary_million;
245  r.uint64_t_value |= random_bits;
246  r.double_value -= binary_million;
247 
248  HeapNumber::cast(heap_number)->set_value(r.double_value);
249  return heap_number;
250 }
251 
252 void V8::InitializeOncePerProcessImpl() {
253  OS::SetUp();
254 
255  use_crankshaft_ = FLAG_crankshaft;
256 
257  if (Serializer::enabled()) {
258  use_crankshaft_ = false;
259  }
260 
261  CPU::SetUp();
262  if (!CPU::SupportsCrankshaft()) {
263  use_crankshaft_ = false;
264  }
265 
266  OS::PostSetUp();
267 
269 
271 
272  if (FLAG_stress_compaction) {
273  FLAG_force_marking_deque_overflows = true;
274  FLAG_gc_global = true;
275  FLAG_max_new_space_size = (1 << (kPageSizeBits - 10)) * 2;
276  }
277 
281  ExternalReference::SetUp();
282 }
283 
284 void V8::InitializeOncePerProcess() {
285  CallOnce(&init_once, &InitializeOncePerProcessImpl);
286 }
287 
288 } } // namespace v8::internal
static bool Initialize(Deserializer *des)
Definition: v8.cc:64
int random()
void(* CallCompletedCallback)()
Definition: v8.h:2694
static void TearDownCaches()
Definition: lithium.cc:122
HandleScopeImplementer * handle_scope_implementer()
Definition: isolate.h:849
V8_DECLARE_ONCE(initialize_gc_once)
static void SetFatalError()
Definition: v8.cc:97
static void FireCallCompletedCallback(Isolate *isolate)
Definition: v8.cc:215
void CallOnce(OnceType *once, NoArgFunction init_func)
Definition: once.h:105
bool Init(Deserializer *des)
Definition: isolate.cc:1741
T & at(int i) const
Definition: list.h:85
static Object * FillHeapNumberWithRandom(Object *heap_number, Context *context)
Definition: v8.cc:236
static bool enabled()
Definition: serialize.h:480
#define ASSERT(condition)
Definition: checks.h:270
static PerIsolateThreadData * CurrentPerIsolateThreadData()
Definition: isolate.h:431
static void SetUpCaches()
Definition: lithium.cc:115
static bool IsDead()
Definition: v8.h:89
bool IsDefaultIsolate() const
Definition: isolate.h:467
unsigned int seed
Definition: test-strings.cc:17
static bool IdleNotification(int hint)
Definition: v8.cc:184
static void SetEntropySource(EntropySource source)
Definition: v8.cc:156
static ThreadId Current()
Definition: isolate.h:153
static void EnterDefaultIsolate()
Definition: isolate.cc:399
uintptr_t(* ReturnAddressLocationResolver)(uintptr_t return_addr_location)
Definition: v8.h:2917
T Remove(int i)
Definition: list-inl.h:116
static void InitializeOncePerProcess()
Definition: elements.cc:1607
static void RemoveCallCompletedCallback(CallCompletedCallback callback)
Definition: v8.cc:205
static void UnregisterAll()
Definition: api.cc:515
static bool SupportsCrankshaft()
LazyDynamicInstance< Mutex, CreateMutexTrait, ThreadSafeInitOnceTrait >::type LazyMutex
Definition: platform.h:556
static void TearDown()
static HeapNumber * cast(Object *obj)
void set_value(double value)
Definition: objects-inl.h:1195
void SetUpJSCallerSavedCodeData()
Definition: frames.cc:1386
static uint32_t RandomPrivate(Isolate *isolate)
Definition: v8.cc:178
static void AddCallCompletedCallback(CallCompletedCallback callback)
Definition: v8.cc:194
static void PostSetUp()
#define HEAP
Definition: isolate.h:1408
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
static void SetReturnAddressLocationResolver(ReturnAddressLocationResolver resolver)
Definition: v8.cc:161
static void TearDown()
Definition: v8.cc:103
bool(* EntropySource)(unsigned char *buffer, size_t length)
Definition: v8.h:2904
static void SetUp()
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:38
const int kPageSizeBits
Definition: v8globals.h:100
static void SetUp()
#define LAZY_MUTEX_INITIALIZER
Definition: platform.h:558
static uint32_t Random(Context *context)
Definition: v8.cc:168