v8  3.14.5(node0.10.28)
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 
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 
109  // The isolate has to be torn down before clearing the LOperand
110  // caches so that the optimizing compiler thread (if running)
111  // doesn't see an inconsistent view of the lithium instructions.
112  isolate->TearDown();
113  delete isolate;
114 
118 
119  is_running_ = false;
120  has_been_disposed_ = true;
121 
122  delete call_completed_callbacks_;
123  call_completed_callbacks_ = NULL;
124 
125  OS::TearDown();
126 }
127 
128 
129 static void seed_random(uint32_t* state) {
130  for (int i = 0; i < 2; ++i) {
131  if (FLAG_random_seed != 0) {
132  state[i] = FLAG_random_seed;
133  } else if (entropy_source != NULL) {
134  uint32_t val;
135  ScopedLock lock(entropy_mutex.Pointer());
136  entropy_source(reinterpret_cast<unsigned char*>(&val), sizeof(uint32_t));
137  state[i] = val;
138  } else {
139  state[i] = random();
140  }
141  }
142 }
143 
144 
145 // Random number generator using George Marsaglia's MWC algorithm.
146 static uint32_t random_base(uint32_t* state) {
147  // Initialize seed using the system random().
148  // No non-zero seed will ever become zero again.
149  if (state[0] == 0) seed_random(state);
150 
151  // Mix the bits. Never replaces state[i] with 0 if it is nonzero.
152  state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16);
153  state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16);
154 
155  return (state[0] << 14) + (state[1] & 0x3FFFF);
156 }
157 
158 
160  entropy_source = source;
161 }
162 
163 
166  StackFrame::SetReturnAddressLocationResolver(resolver);
167 }
168 
169 
170 // Used by JavaScript APIs
171 uint32_t V8::Random(Context* context) {
172  ASSERT(context->IsNativeContext());
173  ByteArray* seed = context->random_seed();
174  return random_base(reinterpret_cast<uint32_t*>(seed->GetDataStartAddress()));
175 }
176 
177 
178 // Used internally by the JIT and memory allocator for security
179 // purposes. So, we keep a different state to prevent informations
180 // leaks that could be used in an exploit.
181 uint32_t V8::RandomPrivate(Isolate* isolate) {
182  ASSERT(isolate == Isolate::Current());
183  return random_base(isolate->private_random_seed());
184 }
185 
186 
187 bool V8::IdleNotification(int hint) {
188  // Returning true tells the caller that there is no need to call
189  // IdleNotification again.
190  if (!FLAG_use_idle_notification) return true;
191 
192  // Tell the heap that it may want to adjust.
193  return HEAP->IdleNotification(hint);
194 }
195 
196 
198  if (call_completed_callbacks_ == NULL) { // Lazy init.
199  call_completed_callbacks_ = new List<CallCompletedCallback>();
200  }
201  for (int i = 0; i < call_completed_callbacks_->length(); i++) {
202  if (callback == call_completed_callbacks_->at(i)) return;
203  }
204  call_completed_callbacks_->Add(callback);
205 }
206 
207 
209  if (call_completed_callbacks_ == NULL) return;
210  for (int i = 0; i < call_completed_callbacks_->length(); i++) {
211  if (callback == call_completed_callbacks_->at(i)) {
212  call_completed_callbacks_->Remove(i);
213  }
214  }
215 }
216 
217 
219  if (call_completed_callbacks_ == NULL) return;
220  HandleScopeImplementer* handle_scope_implementer =
221  isolate->handle_scope_implementer();
222  if (!handle_scope_implementer->CallDepthIsZero()) return;
223  // Fire callbacks. Increase call depth to prevent recursive callbacks.
224  handle_scope_implementer->IncrementCallDepth();
225  for (int i = 0; i < call_completed_callbacks_->length(); i++) {
226  call_completed_callbacks_->at(i)();
227  }
228  handle_scope_implementer->DecrementCallDepth();
229 }
230 
231 
232 // Use a union type to avoid type-aliasing optimizations in GCC.
233 typedef union {
234  double double_value;
235  uint64_t uint64_t_value;
237 
238 
240  Context* context) {
242  uint64_t random_bits = Random(context);
243  // Convert 32 random bits to 0.(32 random bits) in a double
244  // by computing:
245  // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
246  static const double binary_million = 1048576.0;
247  r.double_value = binary_million;
248  r.uint64_t_value |= random_bits;
249  r.double_value -= binary_million;
250 
251  HeapNumber::cast(heap_number)->set_value(r.double_value);
252  return heap_number;
253 }
254 
255 void V8::InitializeOncePerProcessImpl() {
256  OS::SetUp();
257 
258  use_crankshaft_ = FLAG_crankshaft;
259 
260  if (Serializer::enabled()) {
261  use_crankshaft_ = false;
262  }
263 
264  CPU::SetUp();
265  if (!CPU::SupportsCrankshaft()) {
266  use_crankshaft_ = false;
267  }
268 
269  OS::PostSetUp();
270 
272 
274 
275  if (FLAG_stress_compaction) {
276  FLAG_force_marking_deque_overflows = true;
277  FLAG_gc_global = true;
278  FLAG_max_new_space_size = (1 << (kPageSizeBits - 10)) * 2;
279  }
280 
284  ExternalReference::SetUp();
285 }
286 
287 void V8::InitializeOncePerProcess() {
288  CallOnce(&init_once, &InitializeOncePerProcessImpl);
289 }
290 
291 } } // namespace v8::internal
static bool Initialize(Deserializer *des)
Definition: v8.cc:64
int random()
void(* CallCompletedCallback)()
Definition: v8.h:2724
static void TearDownCaches()
Definition: lithium.cc:139
HandleScopeImplementer * handle_scope_implementer()
Definition: isolate.h:864
V8_DECLARE_ONCE(initialize_gc_once)
static void SetFatalError()
Definition: v8.cc:97
static void FireCallCompletedCallback(Isolate *isolate)
Definition: v8.cc:218
void CallOnce(OnceType *once, NoArgFunction init_func)
Definition: once.h:105
bool Init(Deserializer *des)
Definition: isolate.cc:1803
T & at(int i) const
Definition: list.h:90
static Object * FillHeapNumberWithRandom(Object *heap_number, Context *context)
Definition: v8.cc:239
static bool enabled()
Definition: serialize.h:481
#define ASSERT(condition)
Definition: checks.h:270
static PerIsolateThreadData * CurrentPerIsolateThreadData()
Definition: isolate.h:433
static void EnforceFlagImplications()
Definition: flags.cc:542
static void SetUpCaches()
Definition: lithium.cc:132
static bool IsDead()
Definition: v8.h:89
bool IsDefaultIsolate() const
Definition: isolate.h:469
unsigned int seed
Definition: test-strings.cc:18
static bool IdleNotification(int hint)
Definition: v8.cc:187
static void SetEntropySource(EntropySource source)
Definition: v8.cc:159
static ThreadId Current()
Definition: isolate.h:154
static void EnterDefaultIsolate()
Definition: isolate.cc:399
uintptr_t(* ReturnAddressLocationResolver)(uintptr_t return_addr_location)
Definition: v8.h:2950
T Remove(int i)
Definition: list-inl.h:116
static void InitializeOncePerProcess()
Definition: elements.cc:1606
static void RemoveCallCompletedCallback(CallCompletedCallback callback)
Definition: v8.cc:208
static void UnregisterAll()
Definition: api.cc:516
static bool SupportsCrankshaft()
LazyDynamicInstance< Mutex, CreateMutexTrait, ThreadSafeInitOnceTrait >::type LazyMutex
Definition: platform.h:583
static void TearDown()
static HeapNumber * cast(Object *obj)
void set_value(double value)
Definition: objects-inl.h:1203
void SetUpJSCallerSavedCodeData()
Definition: frames.cc:1394
static uint32_t RandomPrivate(Isolate *isolate)
Definition: v8.cc:181
static void AddCallCompletedCallback(CallCompletedCallback callback)
Definition: v8.cc:197
static void PostSetUp()
#define HEAP
Definition: isolate.h:1433
static void SetReturnAddressLocationResolver(ReturnAddressLocationResolver resolver)
Definition: v8.cc:164
static void TearDown()
Definition: v8.cc:103
bool(* EntropySource)(unsigned char *buffer, size_t length)
Definition: v8.h:2934
static void SetUp()
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:38
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
const int kPageSizeBits
Definition: v8globals.h:92
static void SetUp()
#define LAZY_MUTEX_INITIALIZER
Definition: platform.h:585
static uint32_t Random(Context *context)
Definition: v8.cc:171