blob: 945043da9bc23cd100dae7fefea8facbdf0181ad [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// 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"
Ben Murdochb0fe1622011-05-05 13:52:32 +010032#include "deoptimizer.h"
33#include "heap-profiler.h"
34#include "hydrogen.h"
35#include "lithium-allocator.h"
36#include "log.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010037#include "runtime-profiler.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000038#include "serialize.h"
Steve Blockd0582a62009-12-15 09:54:21 +000039#include "simulator.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000040#include "stub-cache.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000041
42namespace v8 {
43namespace internal {
44
45bool V8::is_running_ = false;
46bool V8::has_been_setup_ = false;
47bool V8::has_been_disposed_ = false;
48bool V8::has_fatal_error_ = false;
Ben Murdochb0fe1622011-05-05 13:52:32 +010049bool V8::use_crankshaft_ = true;
Steve Blocka7e24c12009-10-30 11:49:00 +000050
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080051
Steve Block6ded16b2010-05-10 14:33:55 +010052bool V8::Initialize(Deserializer* des) {
Steve Blocka7e24c12009-10-30 11:49:00 +000053 bool create_heap_objects = des == NULL;
54 if (has_been_disposed_ || has_fatal_error_) return false;
55 if (IsRunning()) return true;
56
Ben Murdoche0cee9b2011-05-25 10:26:03 +010057#if defined(V8_TARGET_ARCH_ARM) && !defined(USE_ARM_EABI)
58 use_crankshaft_ = false;
59#else
Ben Murdochb0fe1622011-05-05 13:52:32 +010060 use_crankshaft_ = FLAG_crankshaft;
Ben Murdoche0cee9b2011-05-25 10:26:03 +010061#endif
62
Ben Murdochb0fe1622011-05-05 13:52:32 +010063 // Peephole optimization might interfere with deoptimization.
64 FLAG_peephole_optimization = !use_crankshaft_;
Steve Blocka7e24c12009-10-30 11:49:00 +000065 is_running_ = true;
66 has_been_setup_ = true;
67 has_fatal_error_ = false;
68 has_been_disposed_ = false;
69#ifdef DEBUG
70 // The initialization process does not handle memory exhaustion.
71 DisallowAllocationFailure disallow_allocation_failure;
72#endif
73
74 // Enable logging before setting up the heap
75 Logger::Setup();
Steve Blocka7e24c12009-10-30 11:49:00 +000076
Steve Block6ded16b2010-05-10 14:33:55 +010077 CpuProfiler::Setup();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +010078 HeapProfiler::Setup();
Steve Block6ded16b2010-05-10 14:33:55 +010079
Steve Blocka7e24c12009-10-30 11:49:00 +000080 // Setup the platform OS support.
81 OS::Setup();
82
83 // Initialize other runtime facilities
John Reck59135872010-11-02 12:39:01 -070084#if defined(USE_SIMULATOR)
85#if defined(V8_TARGET_ARCH_ARM)
Steve Block1e0659c2011-05-24 12:43:12 +010086 Simulator::Initialize();
John Reck59135872010-11-02 12:39:01 -070087#elif defined(V8_TARGET_ARCH_MIPS)
88 ::assembler::mips::Simulator::Initialize();
89#endif
Steve Blocka7e24c12009-10-30 11:49:00 +000090#endif
91
92 { // NOLINT
93 // Ensure that the thread has a valid stack guard. The v8::Locker object
94 // will ensure this too, but we don't have to use lockers if we are only
95 // using one thread.
96 ExecutionAccess lock;
97 StackGuard::InitThread(lock);
98 }
99
100 // Setup the object heap
101 ASSERT(!Heap::HasBeenSetup());
102 if (!Heap::Setup(create_heap_objects)) {
103 SetFatalError();
104 return false;
105 }
106
107 Bootstrapper::Initialize(create_heap_objects);
108 Builtins::Setup(create_heap_objects);
109 Top::Initialize();
110
111 if (FLAG_preemption) {
112 v8::Locker locker;
113 v8::Locker::StartPreemption(100);
114 }
115
116#ifdef ENABLE_DEBUGGER_SUPPORT
117 Debug::Setup(create_heap_objects);
118#endif
119 StubCache::Initialize(create_heap_objects);
120
121 // If we are deserializing, read the state into the now-empty heap.
122 if (des != NULL) {
123 des->Deserialize();
124 StubCache::Clear();
125 }
126
127 // Deserializing may put strange things in the root array's copy of the
128 // stack guard.
Steve Blockd0582a62009-12-15 09:54:21 +0000129 Heap::SetStackLimits();
Steve Blocka7e24c12009-10-30 11:49:00 +0000130
131 // Setup the CPU support. Must be done after heap setup and after
132 // any deserialization because we have to have the initial heap
133 // objects in place for creating the code object used for probing.
134 CPU::Setup();
135
Ben Murdochb0fe1622011-05-05 13:52:32 +0100136 Deoptimizer::Setup();
137 LAllocator::Setup();
138 RuntimeProfiler::Setup();
Steve Blocka7e24c12009-10-30 11:49:00 +0000139
Andrei Popescu31002712010-02-23 13:46:05 +0000140 // If we are deserializing, log non-function code objects and compiled
141 // functions found in the snapshot.
142 if (des != NULL && FLAG_log_code) {
Steve Blockd0582a62009-12-15 09:54:21 +0000143 HandleScope scope;
Andrei Popescu31002712010-02-23 13:46:05 +0000144 LOG(LogCodeObjects());
Steve Blockd0582a62009-12-15 09:54:21 +0000145 LOG(LogCompiledFunctions());
146 }
147
Steve Blocka7e24c12009-10-30 11:49:00 +0000148 return true;
149}
150
151
152void V8::SetFatalError() {
153 is_running_ = false;
154 has_fatal_error_ = true;
155}
156
157
158void V8::TearDown() {
159 if (!has_been_setup_ || has_been_disposed_) return;
160
Ben Murdochb0fe1622011-05-05 13:52:32 +0100161 if (FLAG_time_hydrogen) HStatistics::Instance()->Print();
162
163 // We must stop the logger before we tear down other components.
164 Logger::EnsureTickerStopped();
165
166 Deoptimizer::TearDown();
Steve Blocka7e24c12009-10-30 11:49:00 +0000167
168 if (FLAG_preemption) {
169 v8::Locker locker;
170 v8::Locker::StopPreemption();
171 }
172
173 Builtins::TearDown();
174 Bootstrapper::TearDown();
175
176 Top::TearDown();
177
Kristian Monsen9dcf7e22010-06-28 14:14:28 +0100178 HeapProfiler::TearDown();
Steve Block6ded16b2010-05-10 14:33:55 +0100179 CpuProfiler::TearDown();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100180 RuntimeProfiler::TearDown();
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100181
Steve Blocka7e24c12009-10-30 11:49:00 +0000182 Logger::TearDown();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100183 Heap::TearDown();
Steve Blocka7e24c12009-10-30 11:49:00 +0000184
185 is_running_ = false;
186 has_been_disposed_ = true;
187}
188
189
Steve Block6ded16b2010-05-10 14:33:55 +0100190static uint32_t random_seed() {
191 if (FLAG_random_seed == 0) {
192 return random();
193 }
194 return FLAG_random_seed;
195}
196
197
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800198typedef struct {
199 uint32_t hi;
200 uint32_t lo;
201} random_state;
Steve Blocka7e24c12009-10-30 11:49:00 +0000202
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800203
204// Random number generator using George Marsaglia's MWC algorithm.
205static uint32_t random_base(random_state *state) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000206 // Initialize seed using the system random(). If one of the seeds
207 // should ever become zero again, or if random() returns zero, we
208 // avoid getting stuck with zero bits in hi or lo by re-initializing
209 // them on demand.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800210 if (state->hi == 0) state->hi = random_seed();
211 if (state->lo == 0) state->lo = random_seed();
Steve Blocka7e24c12009-10-30 11:49:00 +0000212
213 // Mix the bits.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800214 state->hi = 36969 * (state->hi & 0xFFFF) + (state->hi >> 16);
215 state->lo = 18273 * (state->lo & 0xFFFF) + (state->lo >> 16);
216 return (state->hi << 16) + (state->lo & 0xFFFF);
217}
218
219
220// Used by JavaScript APIs
221uint32_t V8::Random() {
222 static random_state state = {0, 0};
223 return random_base(&state);
224}
225
226
227// Used internally by the JIT and memory allocator for security
228// purposes. So, we keep a different state to prevent informations
229// leaks that could be used in an exploit.
230uint32_t V8::RandomPrivate() {
231 static random_state state = {0, 0};
232 return random_base(&state);
Steve Blocka7e24c12009-10-30 11:49:00 +0000233}
234
235
Steve Block3ce2e202009-11-05 08:53:23 +0000236bool V8::IdleNotification() {
Steve Blocka7e24c12009-10-30 11:49:00 +0000237 // Returning true tells the caller that there is no need to call
238 // IdleNotification again.
239 if (!FLAG_use_idle_notification) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +0000240
241 // Tell the heap that it may want to adjust.
242 return Heap::IdleNotification();
243}
244
245
Steve Block6ded16b2010-05-10 14:33:55 +0100246// Use a union type to avoid type-aliasing optimizations in GCC.
247typedef union {
248 double double_value;
249 uint64_t uint64_t_value;
250} double_int_union;
251
252
253Object* V8::FillHeapNumberWithRandom(Object* heap_number) {
254 uint64_t random_bits = Random();
255 // Make a double* from address (heap_number + sizeof(double)).
256 double_int_union* r = reinterpret_cast<double_int_union*>(
257 reinterpret_cast<char*>(heap_number) +
258 HeapNumber::kValueOffset - kHeapObjectTag);
259 // Convert 32 random bits to 0.(32 random bits) in a double
260 // by computing:
261 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
262 const double binary_million = 1048576.0;
263 r->double_value = binary_million;
264 r->uint64_t_value |= random_bits;
265 r->double_value -= binary_million;
266
267 return heap_number;
Steve Blocka7e24c12009-10-30 11:49:00 +0000268}
269
270} } // namespace v8::internal