blob: 62330c32d482aa9a1a74ba70f38d769bfff240da [file] [log] [blame]
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001// Copyright 2012 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
fschneider@chromium.org7d10be52012-04-10 12:30:14 +000030#include "assembler.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000031#include "isolate.h"
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000032#include "elements.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000033#include "bootstrapper.h"
34#include "debug.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000035#include "deoptimizer.h"
fschneider@chromium.org7d10be52012-04-10 12:30:14 +000036#include "frames.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "heap-profiler.h"
38#include "hydrogen.h"
39#include "lithium-allocator.h"
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +000040#include "objects.h"
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000041#include "once.h"
42#include "platform.h"
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000043#include "sampler.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000044#include "runtime-profiler.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045#include "serialize.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
ager@chromium.orgeadaf222009-06-16 09:43:10 +000047
kasperl@chromium.org71affb52009-05-26 05:44:31 +000048namespace v8 {
49namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000050
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000051V8_DECLARE_ONCE(init_once);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +000052
rossberg@chromium.orgfab14982012-01-05 15:02:15 +000053List<CallCompletedCallback>* V8::call_completed_callbacks_ = NULL;
ulan@chromium.org837a67e2013-06-11 15:39:48 +000054v8::ArrayBuffer::Allocator* V8::array_buffer_allocator_ = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000055
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +000056
whesse@chromium.orgcec079d2010-03-22 14:44:04 +000057bool V8::Initialize(Deserializer* des) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +000058 InitializeOncePerProcess();
59
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000060 // The current thread may not yet had entered an isolate to run.
61 // Note the Isolate::Current() may be non-null because for various
62 // initialization purposes an initializing thread may be assigned an isolate
63 // but not actually enter it.
64 if (i::Isolate::CurrentPerIsolateThreadData() == NULL) {
65 i::Isolate::EnterDefaultIsolate();
66 }
67
68 ASSERT(i::Isolate::CurrentPerIsolateThreadData() != NULL);
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +000069 ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id().Equals(
70 i::ThreadId::Current()));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000071 ASSERT(i::Isolate::CurrentPerIsolateThreadData()->isolate() ==
72 i::Isolate::Current());
73
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000074 Isolate* isolate = Isolate::Current();
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +000075 if (isolate->IsDead()) return false;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000076 if (isolate->IsInitialized()) return true;
kasperl@chromium.org71affb52009-05-26 05:44:31 +000077
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000078 return isolate->Init(des);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000079}
80
81
82void V8::TearDown() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000083 Isolate* isolate = Isolate::Current();
84 ASSERT(isolate->IsDefaultIsolate());
dslomov@chromium.org639bac02013-09-09 11:58:54 +000085 if (!isolate->IsInitialized()) return;
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000086
yangguo@chromium.org304cc332012-07-24 07:59:48 +000087 // The isolate has to be torn down before clearing the LOperand
88 // caches so that the optimizing compiler thread (if running)
89 // doesn't see an inconsistent view of the lithium instructions.
90 isolate->TearDown();
91 delete isolate;
92
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000093 ElementsAccessor::TearDown();
94 LOperand::TearDownCaches();
danno@chromium.org1f34ad32012-11-26 14:53:56 +000095 ExternalReference::TearDownMathExpData();
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000096 RegisteredExtension::UnregisterAll();
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +000097 Isolate::GlobalTearDown();
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000098
rossberg@chromium.orgfab14982012-01-05 15:02:15 +000099 delete call_completed_callbacks_;
100 call_completed_callbacks_ = NULL;
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000101
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000102 Sampler::TearDown();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000103}
104
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000105
ulan@chromium.org967e2702012-02-28 09:49:15 +0000106void V8::SetReturnAddressLocationResolver(
107 ReturnAddressLocationResolver resolver) {
108 StackFrame::SetReturnAddressLocationResolver(resolver);
109}
110
111
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000112// Used by JavaScript APIs
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000113uint32_t V8::Random(Context* context) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000114 ASSERT(context->IsNativeContext());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000115 ByteArray* seed = context->random_seed();
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000116 uint32_t* state = reinterpret_cast<uint32_t*>(seed->GetDataStartAddress());
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000117
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000118 // When we get here, the RNG must have been initialized,
119 // see the Genesis constructor in file bootstrapper.cc.
120 ASSERT_NE(0, state[0]);
121 ASSERT_NE(0, state[1]);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000122
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000123 // Mix the bits. Never replaces state[i] with 0 if it is nonzero.
124 state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16);
125 state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16);
126
127 return (state[0] << 14) + (state[1] & 0x3FFFF);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000128}
129
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000130
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000131void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
132 if (call_completed_callbacks_ == NULL) { // Lazy init.
133 call_completed_callbacks_ = new List<CallCompletedCallback>();
134 }
135 for (int i = 0; i < call_completed_callbacks_->length(); i++) {
136 if (callback == call_completed_callbacks_->at(i)) return;
137 }
138 call_completed_callbacks_->Add(callback);
139}
140
141
142void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
143 if (call_completed_callbacks_ == NULL) return;
144 for (int i = 0; i < call_completed_callbacks_->length(); i++) {
145 if (callback == call_completed_callbacks_->at(i)) {
146 call_completed_callbacks_->Remove(i);
147 }
148 }
149}
150
151
152void V8::FireCallCompletedCallback(Isolate* isolate) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000153 bool has_call_completed_callbacks = call_completed_callbacks_ != NULL;
154 bool observer_delivery_pending =
155 FLAG_harmony_observation && isolate->observer_delivery_pending();
156 if (!has_call_completed_callbacks && !observer_delivery_pending) return;
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000157 HandleScopeImplementer* handle_scope_implementer =
158 isolate->handle_scope_implementer();
159 if (!handle_scope_implementer->CallDepthIsZero()) return;
160 // Fire callbacks. Increase call depth to prevent recursive callbacks.
161 handle_scope_implementer->IncrementCallDepth();
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000162 if (observer_delivery_pending) {
163 JSObject::DeliverChangeRecords(isolate);
164 }
165 if (has_call_completed_callbacks) {
166 for (int i = 0; i < call_completed_callbacks_->length(); i++) {
167 call_completed_callbacks_->at(i)();
168 }
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000169 }
170 handle_scope_implementer->DecrementCallDepth();
171}
172
173
ager@chromium.org357bf652010-04-12 11:30:10 +0000174// Use a union type to avoid type-aliasing optimizations in GCC.
175typedef union {
176 double double_value;
177 uint64_t uint64_t_value;
178} double_int_union;
179
180
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000181Object* V8::FillHeapNumberWithRandom(Object* heap_number,
182 Context* context) {
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000183 double_int_union r;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000184 uint64_t random_bits = Random(context);
ager@chromium.org357bf652010-04-12 11:30:10 +0000185 // Convert 32 random bits to 0.(32 random bits) in a double
186 // by computing:
187 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000188 static const double binary_million = 1048576.0;
189 r.double_value = binary_million;
190 r.uint64_t_value |= random_bits;
191 r.double_value -= binary_million;
ager@chromium.org357bf652010-04-12 11:30:10 +0000192
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000193 HeapNumber::cast(heap_number)->set_value(r.double_value);
ager@chromium.org357bf652010-04-12 11:30:10 +0000194 return heap_number;
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000195}
196
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000197
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000198void V8::InitializeOncePerProcessImpl() {
yangguo@chromium.org28381b42013-01-21 14:39:38 +0000199 FlagList::EnforceFlagImplications();
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000200 if (FLAG_stress_compaction) {
201 FLAG_force_marking_deque_overflows = true;
202 FLAG_gc_global = true;
203 FLAG_max_new_space_size = (1 << (kPageSizeBits - 10)) * 2;
204 }
danno@chromium.orgc16e8282013-08-12 16:17:40 +0000205
rossberg@chromium.org92597162013-08-23 13:28:00 +0000206 if (FLAG_concurrent_recompilation &&
danno@chromium.org59400602013-08-13 17:09:37 +0000207 (FLAG_trace_hydrogen || FLAG_trace_hydrogen_stubs)) {
rossberg@chromium.org92597162013-08-23 13:28:00 +0000208 FLAG_concurrent_recompilation = false;
209 PrintF("Concurrent recompilation has been disabled for tracing.\n");
danno@chromium.orgc16e8282013-08-12 16:17:40 +0000210 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000211
212 if (FLAG_sweeper_threads <= 0) {
213 if (FLAG_concurrent_sweeping) {
214 FLAG_sweeper_threads = SystemThreadManager::
215 NumberOfParallelSystemThreads(
216 SystemThreadManager::CONCURRENT_SWEEPING);
217 } else if (FLAG_parallel_sweeping) {
218 FLAG_sweeper_threads = SystemThreadManager::
219 NumberOfParallelSystemThreads(
220 SystemThreadManager::PARALLEL_SWEEPING);
221 }
222 if (FLAG_sweeper_threads == 0) {
223 FLAG_concurrent_sweeping = false;
224 FLAG_parallel_sweeping = false;
225 }
226 } else if (!FLAG_concurrent_sweeping && !FLAG_parallel_sweeping) {
227 FLAG_sweeper_threads = 0;
228 }
229
rossberg@chromium.org92597162013-08-23 13:28:00 +0000230 if (FLAG_concurrent_recompilation &&
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000231 SystemThreadManager::NumberOfParallelSystemThreads(
232 SystemThreadManager::PARALLEL_RECOMPILATION) == 0) {
rossberg@chromium.org92597162013-08-23 13:28:00 +0000233 FLAG_concurrent_recompilation = false;
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000234 }
235
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000236 Sampler::SetUp();
yangguo@chromium.org28381b42013-01-21 14:39:38 +0000237 CPU::SetUp();
yangguo@chromium.org28381b42013-01-21 14:39:38 +0000238 OS::PostSetUp();
yangguo@chromium.org28381b42013-01-21 14:39:38 +0000239 ElementsAccessor::InitializeOncePerProcess();
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000240 LOperand::SetUpCaches();
fschneider@chromium.org7d10be52012-04-10 12:30:14 +0000241 SetUpJSCallerSavedCodeData();
fschneider@chromium.org7d10be52012-04-10 12:30:14 +0000242 ExternalReference::SetUp();
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +0000243 Bootstrapper::InitializeOncePerProcess();
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000244}
245
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000246
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000247void V8::InitializeOncePerProcess() {
248 CallOnce(&init_once, &InitializeOncePerProcessImpl);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000249}
250
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000251} } // namespace v8::internal