v8.cc revision 6ded16be15dd865a9b21ea304d5273c8be299c87
1// Copyright 2006-2009 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 "bootstrapper.h"
31#include "debug.h"
32#include "serialize.h"
33#include "simulator.h"
34#include "stub-cache.h"
35#include "oprofile-agent.h"
36#include "log.h"
37
38namespace v8 {
39namespace internal {
40
41bool V8::is_running_ = false;
42bool V8::has_been_setup_ = false;
43bool V8::has_been_disposed_ = false;
44bool V8::has_fatal_error_ = false;
45
46bool V8::Initialize(Deserializer* des) {
47  bool create_heap_objects = des == NULL;
48  if (has_been_disposed_ || has_fatal_error_) return false;
49  if (IsRunning()) return true;
50
51  is_running_ = true;
52  has_been_setup_ = true;
53  has_fatal_error_ = false;
54  has_been_disposed_ = false;
55#ifdef DEBUG
56  // The initialization process does not handle memory exhaustion.
57  DisallowAllocationFailure disallow_allocation_failure;
58#endif
59
60  // Enable logging before setting up the heap
61  Logger::Setup();
62
63  CpuProfiler::Setup();
64
65  // Setup the platform OS support.
66  OS::Setup();
67
68  // Initialize other runtime facilities
69#if !V8_HOST_ARCH_ARM && V8_TARGET_ARCH_ARM
70  ::assembler::arm::Simulator::Initialize();
71#endif
72
73  { // NOLINT
74    // Ensure that the thread has a valid stack guard.  The v8::Locker object
75    // will ensure this too, but we don't have to use lockers if we are only
76    // using one thread.
77    ExecutionAccess lock;
78    StackGuard::InitThread(lock);
79  }
80
81  // Setup the object heap
82  ASSERT(!Heap::HasBeenSetup());
83  if (!Heap::Setup(create_heap_objects)) {
84    SetFatalError();
85    return false;
86  }
87
88  Bootstrapper::Initialize(create_heap_objects);
89  Builtins::Setup(create_heap_objects);
90  Top::Initialize();
91
92  if (FLAG_preemption) {
93    v8::Locker locker;
94    v8::Locker::StartPreemption(100);
95  }
96
97#ifdef ENABLE_DEBUGGER_SUPPORT
98  Debug::Setup(create_heap_objects);
99#endif
100  StubCache::Initialize(create_heap_objects);
101
102  // If we are deserializing, read the state into the now-empty heap.
103  if (des != NULL) {
104    des->Deserialize();
105    StubCache::Clear();
106  }
107
108  // Deserializing may put strange things in the root array's copy of the
109  // stack guard.
110  Heap::SetStackLimits();
111
112  // Setup the CPU support. Must be done after heap setup and after
113  // any deserialization because we have to have the initial heap
114  // objects in place for creating the code object used for probing.
115  CPU::Setup();
116
117  OProfileAgent::Initialize();
118
119  // If we are deserializing, log non-function code objects and compiled
120  // functions found in the snapshot.
121  if (des != NULL && FLAG_log_code) {
122    HandleScope scope;
123    LOG(LogCodeObjects());
124    LOG(LogCompiledFunctions());
125  }
126
127  return true;
128}
129
130
131void V8::SetFatalError() {
132  is_running_ = false;
133  has_fatal_error_ = true;
134}
135
136
137void V8::TearDown() {
138  if (!has_been_setup_ || has_been_disposed_) return;
139
140  OProfileAgent::TearDown();
141
142  if (FLAG_preemption) {
143    v8::Locker locker;
144    v8::Locker::StopPreemption();
145  }
146
147  Builtins::TearDown();
148  Bootstrapper::TearDown();
149
150  Top::TearDown();
151
152  Heap::TearDown();
153
154  CpuProfiler::TearDown();
155
156  Logger::TearDown();
157
158  is_running_ = false;
159  has_been_disposed_ = true;
160}
161
162
163static uint32_t random_seed() {
164  if (FLAG_random_seed == 0) {
165    return random();
166  }
167  return FLAG_random_seed;
168}
169
170
171uint32_t V8::Random() {
172  // Random number generator using George Marsaglia's MWC algorithm.
173  static uint32_t hi = 0;
174  static uint32_t lo = 0;
175
176  // Initialize seed using the system random(). If one of the seeds
177  // should ever become zero again, or if random() returns zero, we
178  // avoid getting stuck with zero bits in hi or lo by re-initializing
179  // them on demand.
180  if (hi == 0) hi = random_seed();
181  if (lo == 0) lo = random_seed();
182
183  // Mix the bits.
184  hi = 36969 * (hi & 0xFFFF) + (hi >> 16);
185  lo = 18273 * (lo & 0xFFFF) + (lo >> 16);
186  return (hi << 16) + (lo & 0xFFFF);
187}
188
189
190bool V8::IdleNotification() {
191  // Returning true tells the caller that there is no need to call
192  // IdleNotification again.
193  if (!FLAG_use_idle_notification) return true;
194
195  // Tell the heap that it may want to adjust.
196  return Heap::IdleNotification();
197}
198
199
200// Use a union type to avoid type-aliasing optimizations in GCC.
201typedef union {
202  double double_value;
203  uint64_t uint64_t_value;
204} double_int_union;
205
206
207Object* V8::FillHeapNumberWithRandom(Object* heap_number) {
208  uint64_t random_bits = Random();
209  // Make a double* from address (heap_number + sizeof(double)).
210  double_int_union* r = reinterpret_cast<double_int_union*>(
211      reinterpret_cast<char*>(heap_number) +
212      HeapNumber::kValueOffset - kHeapObjectTag);
213  // Convert 32 random bits to 0.(32 random bits) in a double
214  // by computing:
215  // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
216  const double binary_million = 1048576.0;
217  r->double_value = binary_million;
218  r->uint64_t_value |=  random_bits;
219  r->double_value -= binary_million;
220
221  return heap_number;
222}
223
224} }  // namespace v8::internal
225