blob: c5a5775e5b9e22cbd649720162156b2927e9b99d [file] [log] [blame]
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001// Copyright 2006-2009 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000032#include "deoptimizer.h"
33#include "heap-profiler.h"
34#include "hydrogen.h"
35#include "lithium-allocator.h"
36#include "log.h"
37#include "oprofile-agent.h"
38#include "runtime-profiler.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039#include "serialize.h"
ager@chromium.orgc4c92722009-11-18 14:12:51 +000040#include "simulator.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000041#include "stub-cache.h"
ager@chromium.orgeadaf222009-06-16 09:43:10 +000042
kasperl@chromium.org71affb52009-05-26 05:44:31 +000043namespace v8 {
44namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
kasperl@chromium.org71affb52009-05-26 05:44:31 +000046bool V8::is_running_ = false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000047bool V8::has_been_setup_ = false;
48bool V8::has_been_disposed_ = false;
kasperl@chromium.org71affb52009-05-26 05:44:31 +000049bool V8::has_fatal_error_ = false;
kasperl@chromium.orga5551262010-12-07 12:49:48 +000050bool V8::use_crankshaft_ = true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000051
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +000052
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000053bool V8::Initialize(Deserializer* des) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000054 bool create_heap_objects = des == NULL;
kasperl@chromium.org71affb52009-05-26 05:44:31 +000055 if (has_been_disposed_ || has_fatal_error_) return false;
56 if (IsRunning()) return true;
57
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 use_crankshaft_ = FLAG_crankshaft;
59 // Peephole optimization might interfere with deoptimization.
60 FLAG_peephole_optimization = !use_crankshaft_;
kasperl@chromium.org71affb52009-05-26 05:44:31 +000061 is_running_ = true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000062 has_been_setup_ = true;
kasperl@chromium.org71affb52009-05-26 05:44:31 +000063 has_fatal_error_ = false;
64 has_been_disposed_ = false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000065#ifdef DEBUG
66 // The initialization process does not handle memory exhaustion.
67 DisallowAllocationFailure disallow_allocation_failure;
68#endif
69
70 // Enable logging before setting up the heap
71 Logger::Setup();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000072
lrn@chromium.org25156de2010-04-06 13:10:27 +000073 CpuProfiler::Setup();
whesse@chromium.org2c186ca2010-06-16 11:32:39 +000074 HeapProfiler::Setup();
lrn@chromium.org25156de2010-04-06 13:10:27 +000075
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000076 // Setup the platform OS support.
77 OS::Setup();
78
ager@chromium.orgeadaf222009-06-16 09:43:10 +000079 // Initialize other runtime facilities
lrn@chromium.org303ada72010-10-27 09:33:13 +000080#if defined(USE_SIMULATOR)
81#if defined(V8_TARGET_ARCH_ARM)
ager@chromium.org378b34e2011-01-28 08:04:38 +000082 Simulator::Initialize();
lrn@chromium.org303ada72010-10-27 09:33:13 +000083#elif defined(V8_TARGET_ARCH_MIPS)
84 ::assembler::mips::Simulator::Initialize();
85#endif
ager@chromium.orgeadaf222009-06-16 09:43:10 +000086#endif
87
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +000088 { // NOLINT
89 // Ensure that the thread has a valid stack guard. The v8::Locker object
90 // will ensure this too, but we don't have to use lockers if we are only
91 // using one thread.
92 ExecutionAccess lock;
93 StackGuard::InitThread(lock);
94 }
95
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000096 // Setup the object heap
97 ASSERT(!Heap::HasBeenSetup());
98 if (!Heap::Setup(create_heap_objects)) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +000099 SetFatalError();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000100 return false;
101 }
102
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000103 Bootstrapper::Initialize(create_heap_objects);
104 Builtins::Setup(create_heap_objects);
105 Top::Initialize();
106
107 if (FLAG_preemption) {
108 v8::Locker locker;
109 v8::Locker::StartPreemption(100);
110 }
111
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000112#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000113 Debug::Setup(create_heap_objects);
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000114#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000115 StubCache::Initialize(create_heap_objects);
116
117 // If we are deserializing, read the state into the now-empty heap.
118 if (des != NULL) {
119 des->Deserialize();
120 StubCache::Clear();
121 }
122
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000123 // Deserializing may put strange things in the root array's copy of the
124 // stack guard.
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000125 Heap::SetStackLimits();
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000126
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000127 // Setup the CPU support. Must be done after heap setup and after
128 // any deserialization because we have to have the initial heap
129 // objects in place for creating the code object used for probing.
130 CPU::Setup();
131
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000132 OProfileAgent::Initialize();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000133 Deoptimizer::Setup();
134 LAllocator::Setup();
135 RuntimeProfiler::Setup();
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000136
ager@chromium.org5c838252010-02-19 08:53:10 +0000137 // If we are deserializing, log non-function code objects and compiled
138 // functions found in the snapshot.
139 if (des != NULL && FLAG_log_code) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000140 HandleScope scope;
ager@chromium.org5c838252010-02-19 08:53:10 +0000141 LOG(LogCodeObjects());
ager@chromium.org01beca72009-11-24 14:29:16 +0000142 LOG(LogCompiledFunctions());
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000143 }
144
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000145 return true;
146}
147
148
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000149void V8::SetFatalError() {
150 is_running_ = false;
151 has_fatal_error_ = true;
152}
153
154
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000155void V8::TearDown() {
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000156 if (!has_been_setup_ || has_been_disposed_) return;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000157
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000158 if (FLAG_time_hydrogen) HStatistics::Instance()->Print();
159
160 // We must stop the logger before we tear down other components.
161 Logger::EnsureTickerStopped();
162
163 Deoptimizer::TearDown();
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000164 OProfileAgent::TearDown();
165
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000166 if (FLAG_preemption) {
167 v8::Locker locker;
168 v8::Locker::StopPreemption();
169 }
170
171 Builtins::TearDown();
172 Bootstrapper::TearDown();
173
kasper.lundaf4734f2008-07-28 12:50:18 +0000174 Top::TearDown();
175
whesse@chromium.org2c186ca2010-06-16 11:32:39 +0000176 HeapProfiler::TearDown();
lrn@chromium.org25156de2010-04-06 13:10:27 +0000177 CpuProfiler::TearDown();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000178 RuntimeProfiler::TearDown();
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000179
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000180 Logger::TearDown();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000181 Heap::TearDown();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000182
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000183 is_running_ = false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000184 has_been_disposed_ = true;
185}
186
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000187
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +0000188static uint32_t random_seed() {
189 if (FLAG_random_seed == 0) {
190 return random();
191 }
192 return FLAG_random_seed;
193}
194
195
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000196typedef struct {
197 uint32_t hi;
198 uint32_t lo;
199} random_state;
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000200
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000201
202// Random number generator using George Marsaglia's MWC algorithm.
203static uint32_t random_base(random_state *state) {
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000204 // Initialize seed using the system random(). If one of the seeds
205 // should ever become zero again, or if random() returns zero, we
206 // avoid getting stuck with zero bits in hi or lo by re-initializing
207 // them on demand.
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000208 if (state->hi == 0) state->hi = random_seed();
209 if (state->lo == 0) state->lo = random_seed();
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000210
211 // Mix the bits.
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000212 state->hi = 36969 * (state->hi & 0xFFFF) + (state->hi >> 16);
213 state->lo = 18273 * (state->lo & 0xFFFF) + (state->lo >> 16);
214 return (state->hi << 16) + (state->lo & 0xFFFF);
215}
216
217
218// Used by JavaScript APIs
219uint32_t V8::Random() {
220 static random_state state = {0, 0};
221 return random_base(&state);
222}
223
224
225// Used internally by the JIT and memory allocator for security
226// purposes. So, we keep a different state to prevent informations
227// leaks that could be used in an exploit.
228uint32_t V8::RandomPrivate() {
229 static random_state state = {0, 0};
230 return random_base(&state);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000231}
232
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000233
sgjesse@chromium.orgc5145742009-10-07 09:00:33 +0000234bool V8::IdleNotification() {
235 // Returning true tells the caller that there is no need to call
236 // IdleNotification again.
237 if (!FLAG_use_idle_notification) return true;
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000238
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000239 // Tell the heap that it may want to adjust.
240 return Heap::IdleNotification();
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000241}
242
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000243
ager@chromium.org357bf652010-04-12 11:30:10 +0000244// Use a union type to avoid type-aliasing optimizations in GCC.
245typedef union {
246 double double_value;
247 uint64_t uint64_t_value;
248} double_int_union;
249
250
251Object* V8::FillHeapNumberWithRandom(Object* heap_number) {
252 uint64_t random_bits = Random();
253 // Make a double* from address (heap_number + sizeof(double)).
254 double_int_union* r = reinterpret_cast<double_int_union*>(
255 reinterpret_cast<char*>(heap_number) +
256 HeapNumber::kValueOffset - kHeapObjectTag);
257 // Convert 32 random bits to 0.(32 random bits) in a double
258 // by computing:
259 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
260 const double binary_million = 1048576.0;
261 r->double_value = binary_million;
262 r->uint64_t_value |= random_bits;
263 r->double_value -= binary_million;
264
265 return heap_number;
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000266}
267
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268} } // namespace v8::internal