OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 cache_->set(length + 1, *fun); | 84 cache_->set(length + 1, *fun); |
85 Script::cast(fun->shared()->script())->set_type(Smi::FromInt(type_)); | 85 Script::cast(fun->shared()->script())->set_type(Smi::FromInt(type_)); |
86 } | 86 } |
87 | 87 |
88 private: | 88 private: |
89 Script::Type type_; | 89 Script::Type type_; |
90 FixedArray* cache_; | 90 FixedArray* cache_; |
91 DISALLOW_COPY_AND_ASSIGN(SourceCodeCache); | 91 DISALLOW_COPY_AND_ASSIGN(SourceCodeCache); |
92 }; | 92 }; |
93 | 93 |
94 static SourceCodeCache natives_cache(Script::TYPE_NATIVE); | 94 class Genesis; |
95 static SourceCodeCache extensions_cache(Script::TYPE_EXTENSION); | |
96 // This is for delete, not delete[]. | |
97 static List<char*>* delete_these_non_arrays_on_tear_down = NULL; | |
98 | 95 |
| 96 class BootstrapperPrivateData { |
| 97 public: |
| 98 SourceCodeCache natives_cache_; |
| 99 SourceCodeCache extensions_cache_; |
| 100 Genesis* current_; |
| 101 // This is for delete, not delete[]. |
| 102 List<char*>* delete_these_non_arrays_on_tear_down_; |
| 103 |
| 104 List<Object*> code_; |
| 105 List<const char*> name_; |
| 106 List<int> pc_; |
| 107 List<uint32_t> flags_; |
| 108 |
| 109 BootstrapperPrivateData() |
| 110 :delete_these_non_arrays_on_tear_down_(NULL), |
| 111 current_(NULL), |
| 112 extensions_cache_(Script::TYPE_EXTENSION), |
| 113 natives_cache_(Script::TYPE_NATIVE), |
| 114 code_(0), |
| 115 name_(0), |
| 116 pc_(0), |
| 117 flags_(0) { |
| 118 } |
| 119 |
| 120 DISALLOW_COPY_AND_ASSIGN(BootstrapperPrivateData); |
| 121 }; |
| 122 |
| 123 BootstrapperData::BootstrapperData() |
| 124 :private_data_(*new BootstrapperPrivateData()) { |
| 125 } |
| 126 |
| 127 BootstrapperData::~BootstrapperData() { |
| 128 delete &private_data_; |
| 129 } |
99 | 130 |
100 NativesExternalStringResource::NativesExternalStringResource(const char* source) | 131 NativesExternalStringResource::NativesExternalStringResource(const char* source) |
101 : data_(source), length_(StrLength(source)) { | 132 : data_(source), length_(StrLength(source)) { |
102 if (delete_these_non_arrays_on_tear_down == NULL) { | 133 BootstrapperPrivateData& data = v8_context()->bootstrapper_data_. |
103 delete_these_non_arrays_on_tear_down = new List<char*>(2); | 134 private_data_; |
| 135 if (data.delete_these_non_arrays_on_tear_down_ == NULL) { |
| 136 data.delete_these_non_arrays_on_tear_down_ = new List<char*>(2); |
104 } | 137 } |
105 // The resources are small objects and we only make a fixed number of | 138 // The resources are small objects and we only make a fixed number of |
106 // them, but let's clean them up on exit for neatness. | 139 // them, but let's clean them up on exit for neatness. |
107 delete_these_non_arrays_on_tear_down-> | 140 data.delete_these_non_arrays_on_tear_down_-> |
108 Add(reinterpret_cast<char*>(this)); | 141 Add(reinterpret_cast<char*>(this)); |
109 } | 142 } |
110 | 143 |
111 | 144 |
112 Handle<String> Bootstrapper::NativesSourceLookup(int index) { | 145 Handle<String> Bootstrapper::NativesSourceLookup(int index) { |
113 ASSERT(0 <= index && index < Natives::GetBuiltinsCount()); | 146 ASSERT(0 <= index && index < Natives::GetBuiltinsCount()); |
114 if (Heap::natives_source_cache()->get(index)->IsUndefined()) { | 147 if (Heap::natives_source_cache()->get(index)->IsUndefined()) { |
115 if (!Snapshot::IsEnabled() || FLAG_new_snapshot) { | 148 if (!Snapshot::IsEnabled() || FLAG_new_snapshot) { |
116 // We can use external strings for the natives. | 149 // We can use external strings for the natives. |
117 NativesExternalStringResource* resource = | 150 NativesExternalStringResource* resource = |
118 new NativesExternalStringResource( | 151 new NativesExternalStringResource( |
119 Natives::GetScriptSource(index).start()); | 152 Natives::GetScriptSource(index).start()); |
120 Handle<String> source_code = | 153 Handle<String> source_code = |
121 Factory::NewExternalStringFromAscii(resource); | 154 Factory::NewExternalStringFromAscii(resource); |
122 Heap::natives_source_cache()->set(index, *source_code); | 155 Heap::natives_source_cache()->set(index, *source_code); |
123 } else { | 156 } else { |
124 // Old snapshot code can't cope with external strings at all. | 157 // Old snapshot code can't cope with external strings at all. |
125 Handle<String> source_code = | 158 Handle<String> source_code = |
126 Factory::NewStringFromAscii(Natives::GetScriptSource(index)); | 159 Factory::NewStringFromAscii(Natives::GetScriptSource(index)); |
127 Heap::natives_source_cache()->set(index, *source_code); | 160 Heap::natives_source_cache()->set(index, *source_code); |
128 } | 161 } |
129 } | 162 } |
130 Handle<Object> cached_source(Heap::natives_source_cache()->get(index)); | 163 Handle<Object> cached_source(Heap::natives_source_cache()->get(index)); |
131 return Handle<String>::cast(cached_source); | 164 return Handle<String>::cast(cached_source); |
132 } | 165 } |
133 | 166 |
134 | 167 |
135 bool Bootstrapper::NativesCacheLookup(Vector<const char> name, | 168 bool Bootstrapper::NativesCacheLookup(Vector<const char> name, |
136 Handle<JSFunction>* handle) { | 169 Handle<JSFunction>* handle) { |
137 return natives_cache.Lookup(name, handle); | 170 return v8_context()->bootstrapper_data_. |
| 171 private_data_.natives_cache_.Lookup(name, handle); |
138 } | 172 } |
139 | 173 |
140 | 174 |
141 void Bootstrapper::NativesCacheAdd(Vector<const char> name, | 175 void Bootstrapper::NativesCacheAdd(Vector<const char> name, |
142 Handle<JSFunction> fun) { | 176 Handle<JSFunction> fun) { |
143 natives_cache.Add(name, fun); | 177 v8_context()->bootstrapper_data_. |
| 178 private_data_.natives_cache_.Add(name, fun); |
144 } | 179 } |
145 | 180 |
146 | 181 |
147 void Bootstrapper::Initialize(bool create_heap_objects) { | 182 void Bootstrapper::Initialize(bool create_heap_objects) { |
148 natives_cache.Initialize(create_heap_objects); | 183 BootstrapperPrivateData& data = v8_context()->bootstrapper_data_. |
149 extensions_cache.Initialize(create_heap_objects); | 184 private_data_; |
| 185 data.natives_cache_.Initialize(create_heap_objects); |
| 186 data.extensions_cache_.Initialize(create_heap_objects); |
150 } | 187 } |
151 | 188 |
152 | 189 |
153 void Bootstrapper::TearDown() { | 190 void Bootstrapper::TearDown() { |
154 if (delete_these_non_arrays_on_tear_down != NULL) { | 191 BootstrapperPrivateData& data = v8_context()->bootstrapper_data_. |
155 int len = delete_these_non_arrays_on_tear_down->length(); | 192 private_data_; |
| 193 if (data.delete_these_non_arrays_on_tear_down_ != NULL) { |
| 194 int len = data.delete_these_non_arrays_on_tear_down_->length(); |
156 ASSERT(len < 20); // Don't use this mechanism for unbounded allocations. | 195 ASSERT(len < 20); // Don't use this mechanism for unbounded allocations. |
157 for (int i = 0; i < len; i++) { | 196 for (int i = 0; i < len; i++) { |
158 delete delete_these_non_arrays_on_tear_down->at(i); | 197 delete data.delete_these_non_arrays_on_tear_down_->at(i); |
159 } | 198 } |
160 delete delete_these_non_arrays_on_tear_down; | 199 delete data.delete_these_non_arrays_on_tear_down_; |
161 delete_these_non_arrays_on_tear_down = NULL; | 200 data.delete_these_non_arrays_on_tear_down_ = NULL; |
162 } | 201 } |
163 | 202 |
164 natives_cache.Initialize(false); // Yes, symmetrical | 203 data.natives_cache_.Initialize(false); // Yes, symmetrical |
165 extensions_cache.Initialize(false); | 204 data.extensions_cache_.Initialize(false); |
166 } | 205 } |
167 | 206 |
168 | 207 |
169 // Pending fixups are code positions that refer to builtin code | 208 // Pending fixups are code positions that refer to builtin code |
170 // objects that were not available at the time the code was generated. | 209 // objects that were not available at the time the code was generated. |
171 // The pending list is processed whenever an environment has been | 210 // The pending list is processed whenever an environment has been |
172 // created. | 211 // created. |
173 class PendingFixups : public AllStatic { | 212 class PendingFixups : public AllStatic { |
174 public: | 213 public: |
175 static void Add(Code* code, MacroAssembler* masm); | 214 static void Add(Code* code, MacroAssembler* masm); |
176 static bool Process(Handle<JSBuiltinsObject> builtins); | 215 static bool Process(Handle<JSBuiltinsObject> builtins); |
177 | 216 |
178 static void Iterate(ObjectVisitor* v); | 217 static void Iterate(ObjectVisitor* v); |
179 | 218 |
180 private: | 219 private: |
181 static List<Object*> code_; | |
182 static List<const char*> name_; | |
183 static List<int> pc_; | |
184 static List<uint32_t> flags_; | |
185 | |
186 static void Clear(); | 220 static void Clear(); |
187 }; | 221 }; |
188 | 222 |
189 | |
190 List<Object*> PendingFixups::code_(0); | |
191 List<const char*> PendingFixups::name_(0); | |
192 List<int> PendingFixups::pc_(0); | |
193 List<uint32_t> PendingFixups::flags_(0); | |
194 | |
195 | |
196 void PendingFixups::Add(Code* code, MacroAssembler* masm) { | 223 void PendingFixups::Add(Code* code, MacroAssembler* masm) { |
197 // Note this code is not only called during bootstrapping. | 224 // Note this code is not only called during bootstrapping. |
198 List<MacroAssembler::Unresolved>* unresolved = masm->unresolved(); | 225 List<MacroAssembler::Unresolved>* unresolved = masm->unresolved(); |
199 int n = unresolved->length(); | 226 int n = unresolved->length(); |
| 227 BootstrapperPrivateData& data = v8_context()->bootstrapper_data_. |
| 228 private_data_; |
200 for (int i = 0; i < n; i++) { | 229 for (int i = 0; i < n; i++) { |
201 const char* name = unresolved->at(i).name; | 230 const char* name = unresolved->at(i).name; |
202 code_.Add(code); | 231 data.code_.Add(code); |
203 name_.Add(name); | 232 data.name_.Add(name); |
204 pc_.Add(unresolved->at(i).pc); | 233 data.pc_.Add(unresolved->at(i).pc); |
205 flags_.Add(unresolved->at(i).flags); | 234 data.flags_.Add(unresolved->at(i).flags); |
206 LOG(StringEvent("unresolved", name)); | 235 LOG(StringEvent("unresolved", name)); |
207 } | 236 } |
208 } | 237 } |
209 | 238 |
210 | 239 |
211 bool PendingFixups::Process(Handle<JSBuiltinsObject> builtins) { | 240 bool PendingFixups::Process(Handle<JSBuiltinsObject> builtins) { |
212 HandleScope scope; | 241 HandleScope scope; |
| 242 BootstrapperPrivateData& data = v8_context()->bootstrapper_data_. |
| 243 private_data_; |
213 // NOTE: Extra fixups may be added to the list during the iteration | 244 // NOTE: Extra fixups may be added to the list during the iteration |
214 // due to lazy compilation of functions during the processing. Do not | 245 // due to lazy compilation of functions during the processing. Do not |
215 // cache the result of getting the length of the code list. | 246 // cache the result of getting the length of the code list. |
216 for (int i = 0; i < code_.length(); i++) { | 247 for (int i = 0; i < data.code_.length(); i++) { |
217 const char* name = name_[i]; | 248 const char* name = data.name_[i]; |
218 uint32_t flags = flags_[i]; | 249 uint32_t flags = data.flags_[i]; |
219 Handle<String> symbol = Factory::LookupAsciiSymbol(name); | 250 Handle<String> symbol = Factory::LookupAsciiSymbol(name); |
220 Object* o = builtins->GetProperty(*symbol); | 251 Object* o = builtins->GetProperty(*symbol); |
221 #ifdef DEBUG | 252 #ifdef DEBUG |
222 if (!o->IsJSFunction()) { | 253 if (!o->IsJSFunction()) { |
223 V8_Fatal(__FILE__, __LINE__, "Cannot resolve call to builtin %s", name); | 254 V8_Fatal(__FILE__, __LINE__, "Cannot resolve call to builtin %s", name); |
224 } | 255 } |
225 #endif | 256 #endif |
226 Handle<JSFunction> f = Handle<JSFunction>(JSFunction::cast(o)); | 257 Handle<JSFunction> f = Handle<JSFunction>(JSFunction::cast(o)); |
227 // Make sure the number of parameters match the formal parameter count. | 258 // Make sure the number of parameters match the formal parameter count. |
228 int argc = Bootstrapper::FixupFlagsArgumentsCount::decode(flags); | 259 int argc = Bootstrapper::FixupFlagsArgumentsCount::decode(flags); |
229 USE(argc); | 260 USE(argc); |
230 ASSERT(f->shared()->formal_parameter_count() == argc); | 261 ASSERT(f->shared()->formal_parameter_count() == argc); |
231 if (!f->is_compiled()) { | 262 if (!f->is_compiled()) { |
232 // Do lazy compilation and check for stack overflows. | 263 // Do lazy compilation and check for stack overflows. |
233 if (!CompileLazy(f, CLEAR_EXCEPTION)) { | 264 if (!CompileLazy(f, CLEAR_EXCEPTION)) { |
234 Clear(); | 265 Clear(); |
235 return false; | 266 return false; |
236 } | 267 } |
237 } | 268 } |
238 Code* code = Code::cast(code_[i]); | 269 Code* code = Code::cast(data.code_[i]); |
239 Address pc = code->instruction_start() + pc_[i]; | 270 Address pc = code->instruction_start() + data.pc_[i]; |
240 RelocInfo target(pc, RelocInfo::CODE_TARGET, 0); | 271 RelocInfo target(pc, RelocInfo::CODE_TARGET, 0); |
241 bool use_code_object = Bootstrapper::FixupFlagsUseCodeObject::decode(flags); | 272 bool use_code_object = Bootstrapper::FixupFlagsUseCodeObject::decode(flags); |
242 if (use_code_object) { | 273 if (use_code_object) { |
243 target.set_target_object(f->code()); | 274 target.set_target_object(f->code()); |
244 } else { | 275 } else { |
245 target.set_target_address(f->code()->instruction_start()); | 276 target.set_target_address(f->code()->instruction_start()); |
246 } | 277 } |
247 LOG(StringEvent("resolved", name)); | 278 LOG(StringEvent("resolved", name)); |
248 } | 279 } |
249 Clear(); | 280 Clear(); |
250 | 281 |
251 // TODO(1240818): We should probably try to avoid doing this for all | 282 // TODO(1240818): We should probably try to avoid doing this for all |
252 // the V8 builtin JS files. It should only happen after running | 283 // the V8 builtin JS files. It should only happen after running |
253 // runtime.js - just like there shouldn't be any fixups left after | 284 // runtime.js - just like there shouldn't be any fixups left after |
254 // that. | 285 // that. |
255 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { | 286 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { |
256 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); | 287 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); |
257 Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id)); | 288 Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id)); |
258 JSFunction* function = JSFunction::cast(builtins->GetProperty(*name)); | 289 JSFunction* function = JSFunction::cast(builtins->GetProperty(*name)); |
259 builtins->set_javascript_builtin(id, function); | 290 builtins->set_javascript_builtin(id, function); |
260 } | 291 } |
261 | 292 |
262 return true; | 293 return true; |
263 } | 294 } |
264 | 295 |
265 | 296 |
266 void PendingFixups::Clear() { | 297 void PendingFixups::Clear() { |
267 code_.Clear(); | 298 BootstrapperPrivateData& data = v8_context()->bootstrapper_data_. |
268 name_.Clear(); | 299 private_data_; |
269 pc_.Clear(); | 300 data.code_.Clear(); |
270 flags_.Clear(); | 301 data.name_.Clear(); |
| 302 data.pc_.Clear(); |
| 303 data.flags_.Clear(); |
271 } | 304 } |
272 | 305 |
273 | 306 |
274 void PendingFixups::Iterate(ObjectVisitor* v) { | 307 void PendingFixups::Iterate(ObjectVisitor* v) { |
275 if (!code_.is_empty()) { | 308 BootstrapperPrivateData& data = v8_context()->bootstrapper_data_. |
276 v->VisitPointers(&code_[0], &code_[0] + code_.length()); | 309 private_data_; |
| 310 if (!data.code_.is_empty()) { |
| 311 v->VisitPointers(&data.code_[0], &data.code_[0] + data.code_.length()); |
277 } | 312 } |
278 } | 313 } |
279 | 314 |
280 | 315 |
281 class Genesis BASE_EMBEDDED { | 316 class Genesis BASE_EMBEDDED { |
282 public: | 317 public: |
283 Genesis(Handle<Object> global_object, | 318 Genesis(Handle<Object> global_object, |
284 v8::Handle<v8::ObjectTemplate> global_template, | 319 v8::Handle<v8::ObjectTemplate> global_template, |
285 v8::ExtensionConfiguration* extensions); | 320 v8::ExtensionConfiguration* extensions); |
286 ~Genesis(); | 321 ~Genesis(); |
287 | 322 |
288 Handle<Context> result() { return result_; } | 323 Handle<Context> result() { return result_; } |
289 | 324 |
290 Genesis* previous() { return previous_; } | 325 Genesis* previous() { return previous_; } |
291 static Genesis* current() { return current_; } | 326 static Genesis* current() { |
| 327 return v8_context()->bootstrapper_data_.private_data_.current_; |
| 328 } |
292 | 329 |
293 // Support for thread preemption. | 330 // Support for thread preemption. |
294 static int ArchiveSpacePerThread(); | 331 static int ArchiveSpacePerThread(); |
295 static char* ArchiveState(char* to); | 332 static char* ArchiveState(char* to); |
296 static char* RestoreState(char* from); | 333 static char* RestoreState(char* from); |
297 | 334 |
298 private: | 335 private: |
299 Handle<Context> global_context_; | 336 Handle<Context> global_context_; |
300 | 337 |
301 // There may be more than one active genesis object: When GC is | 338 // There may be more than one active genesis object: When GC is |
302 // triggered during environment creation there may be weak handle | 339 // triggered during environment creation there may be weak handle |
303 // processing callbacks which may create new environments. | 340 // processing callbacks which may create new environments. |
304 Genesis* previous_; | 341 Genesis* previous_; |
305 static Genesis* current_; | |
306 | 342 |
307 Handle<Context> global_context() { return global_context_; } | 343 Handle<Context> global_context() { return global_context_; } |
308 | 344 |
309 void CreateRoots(v8::Handle<v8::ObjectTemplate> global_template, | 345 void CreateRoots(v8::Handle<v8::ObjectTemplate> global_template, |
310 Handle<Object> global_object); | 346 Handle<Object> global_object); |
311 void InstallNativeFunctions(); | 347 void InstallNativeFunctions(); |
312 bool InstallNatives(); | 348 bool InstallNatives(); |
313 bool InstallExtensions(v8::ExtensionConfiguration* extensions); | 349 bool InstallExtensions(v8::ExtensionConfiguration* extensions); |
314 bool InstallExtension(const char* name); | 350 bool InstallExtension(const char* name); |
315 bool InstallExtension(v8::RegisteredExtension* current); | 351 bool InstallExtension(v8::RegisteredExtension* current); |
(...skipping 24 matching lines...) Expand all Loading... |
340 static bool CompileNative(Vector<const char> name, Handle<String> source); | 376 static bool CompileNative(Vector<const char> name, Handle<String> source); |
341 static bool CompileScriptCached(Vector<const char> name, | 377 static bool CompileScriptCached(Vector<const char> name, |
342 Handle<String> source, | 378 Handle<String> source, |
343 SourceCodeCache* cache, | 379 SourceCodeCache* cache, |
344 v8::Extension* extension, | 380 v8::Extension* extension, |
345 bool use_runtime_context); | 381 bool use_runtime_context); |
346 | 382 |
347 Handle<Context> result_; | 383 Handle<Context> result_; |
348 }; | 384 }; |
349 | 385 |
350 Genesis* Genesis::current_ = NULL; | |
351 | 386 |
352 | 387 |
353 void Bootstrapper::Iterate(ObjectVisitor* v) { | 388 void Bootstrapper::Iterate(ObjectVisitor* v) { |
354 natives_cache.Iterate(v); | 389 BootstrapperPrivateData& data = v8_context()->bootstrapper_data_. |
| 390 private_data_; |
| 391 data.natives_cache_.Iterate(v); |
355 v->Synchronize("NativesCache"); | 392 v->Synchronize("NativesCache"); |
356 extensions_cache.Iterate(v); | 393 data.extensions_cache_.Iterate(v); |
357 v->Synchronize("Extensions"); | 394 v->Synchronize("Extensions"); |
358 PendingFixups::Iterate(v); | 395 PendingFixups::Iterate(v); |
359 v->Synchronize("PendingFixups"); | 396 v->Synchronize("PendingFixups"); |
360 } | 397 } |
361 | 398 |
362 | 399 |
363 // While setting up the environment, we collect code positions that | 400 // While setting up the environment, we collect code positions that |
364 // need to be patched before we can run any code in the environment. | 401 // need to be patched before we can run any code in the environment. |
365 void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) { | 402 void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) { |
366 PendingFixups::Add(code, masm); | 403 PendingFixups::Add(code, masm); |
(...skipping 26 matching lines...) Expand all Loading... |
393 void Bootstrapper::DetachGlobal(Handle<Context> env) { | 430 void Bootstrapper::DetachGlobal(Handle<Context> env) { |
394 JSGlobalProxy::cast(env->global_proxy())->set_context(*Factory::null_value()); | 431 JSGlobalProxy::cast(env->global_proxy())->set_context(*Factory::null_value()); |
395 SetObjectPrototype(Handle<JSObject>(env->global_proxy()), | 432 SetObjectPrototype(Handle<JSObject>(env->global_proxy()), |
396 Factory::null_value()); | 433 Factory::null_value()); |
397 env->set_global_proxy(env->global()); | 434 env->set_global_proxy(env->global()); |
398 env->global()->set_global_receiver(env->global()); | 435 env->global()->set_global_receiver(env->global()); |
399 } | 436 } |
400 | 437 |
401 | 438 |
402 Genesis::~Genesis() { | 439 Genesis::~Genesis() { |
403 ASSERT(current_ == this); | 440 Genesis* & current = v8_context()->bootstrapper_data_.private_data_.current_; |
404 current_ = previous_; | 441 ASSERT(current == this); |
| 442 current = previous_; |
405 } | 443 } |
406 | 444 |
407 | 445 |
408 static Handle<JSFunction> InstallFunction(Handle<JSObject> target, | 446 static Handle<JSFunction> InstallFunction(Handle<JSObject> target, |
409 const char* name, | 447 const char* name, |
410 InstanceType type, | 448 InstanceType type, |
411 int instance_size, | 449 int instance_size, |
412 Handle<JSObject> prototype, | 450 Handle<JSObject> prototype, |
413 Builtins::Name call, | 451 Builtins::Name call, |
414 bool is_ecma_native) { | 452 bool is_ecma_native) { |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 Handle<String> source_code = Bootstrapper::NativesSourceLookup(index); | 924 Handle<String> source_code = Bootstrapper::NativesSourceLookup(index); |
887 return CompileNative(name, source_code); | 925 return CompileNative(name, source_code); |
888 } | 926 } |
889 | 927 |
890 | 928 |
891 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) { | 929 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) { |
892 HandleScope scope; | 930 HandleScope scope; |
893 #ifdef ENABLE_DEBUGGER_SUPPORT | 931 #ifdef ENABLE_DEBUGGER_SUPPORT |
894 Debugger::set_compiling_natives(true); | 932 Debugger::set_compiling_natives(true); |
895 #endif | 933 #endif |
896 bool result = | 934 bool result = CompileScriptCached(name, source, |
897 CompileScriptCached(name, source, &natives_cache, NULL, true); | 935 &v8_context()->bootstrapper_data_.private_data_.natives_cache_, NULL, true); |
898 ASSERT(Top::has_pending_exception() != result); | 936 ASSERT(Top::has_pending_exception() != result); |
899 if (!result) Top::clear_pending_exception(); | 937 if (!result) Top::clear_pending_exception(); |
900 #ifdef ENABLE_DEBUGGER_SUPPORT | 938 #ifdef ENABLE_DEBUGGER_SUPPORT |
901 Debugger::set_compiling_natives(false); | 939 Debugger::set_compiling_natives(false); |
902 #endif | 940 #endif |
903 return result; | 941 return result; |
904 } | 942 } |
905 | 943 |
906 | 944 |
907 bool Genesis::CompileScriptCached(Vector<const char> name, | 945 bool Genesis::CompileScriptCached(Vector<const char> name, |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1263 Factory::LookupAsciiSymbol(FLAG_expose_debug_as); | 1301 Factory::LookupAsciiSymbol(FLAG_expose_debug_as); |
1264 SetProperty(js_global, debug_string, | 1302 SetProperty(js_global, debug_string, |
1265 Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM); | 1303 Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM); |
1266 } | 1304 } |
1267 #endif | 1305 #endif |
1268 | 1306 |
1269 return true; | 1307 return true; |
1270 } | 1308 } |
1271 | 1309 |
1272 | 1310 |
| 1311 static MutexLockAdapter genesis_lock_adapter(OS::CreateMutex()); |
| 1312 |
1273 bool Genesis::InstallExtensions(v8::ExtensionConfiguration* extensions) { | 1313 bool Genesis::InstallExtensions(v8::ExtensionConfiguration* extensions) { |
| 1314 V8SharedStateLocker locker(&genesis_lock_adapter); |
1274 // Clear coloring of extension list | 1315 // Clear coloring of extension list |
1275 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); | 1316 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); |
1276 while (current != NULL) { | 1317 while (current != NULL) { |
1277 current->set_state(v8::UNVISITED); | 1318 current->set_state(v8::UNVISITED); |
1278 current = current->next(); | 1319 current = current->next(); |
1279 } | 1320 } |
1280 // Install auto extensions | 1321 // Install auto extensions |
1281 current = v8::RegisteredExtension::first_extension(); | 1322 current = v8::RegisteredExtension::first_extension(); |
1282 while (current != NULL) { | 1323 while (current != NULL) { |
1283 if (current->extension()->auto_enable()) | 1324 if (current->extension()->auto_enable()) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 } | 1373 } |
1333 ASSERT(current->state() == v8::UNVISITED); | 1374 ASSERT(current->state() == v8::UNVISITED); |
1334 current->set_state(v8::VISITED); | 1375 current->set_state(v8::VISITED); |
1335 v8::Extension* extension = current->extension(); | 1376 v8::Extension* extension = current->extension(); |
1336 // Install the extension's dependencies | 1377 // Install the extension's dependencies |
1337 for (int i = 0; i < extension->dependency_count(); i++) { | 1378 for (int i = 0; i < extension->dependency_count(); i++) { |
1338 if (!InstallExtension(extension->dependencies()[i])) return false; | 1379 if (!InstallExtension(extension->dependencies()[i])) return false; |
1339 } | 1380 } |
1340 Vector<const char> source = CStrVector(extension->source()); | 1381 Vector<const char> source = CStrVector(extension->source()); |
1341 Handle<String> source_code = Factory::NewStringFromAscii(source); | 1382 Handle<String> source_code = Factory::NewStringFromAscii(source); |
1342 bool result = CompileScriptCached(CStrVector(extension->name()), | 1383 bool result = CompileScriptCached( |
1343 source_code, | 1384 CStrVector(extension->name()), |
1344 &extensions_cache, extension, | 1385 source_code, |
1345 false); | 1386 &v8_context()->bootstrapper_data_.private_data_.extensions_cache_, |
| 1387 extension, |
| 1388 false); |
1346 ASSERT(Top::has_pending_exception() != result); | 1389 ASSERT(Top::has_pending_exception() != result); |
1347 if (!result) { | 1390 if (!result) { |
1348 Top::clear_pending_exception(); | 1391 Top::clear_pending_exception(); |
1349 } | 1392 } |
1350 current->set_state(v8::INSTALLED); | 1393 current->set_state(v8::INSTALLED); |
1351 return result; | 1394 return result; |
1352 } | 1395 } |
1353 | 1396 |
1354 | 1397 |
1355 bool Genesis::ConfigureGlobalObjects( | 1398 bool Genesis::ConfigureGlobalObjects( |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1568 Handle<Code>(Builtins::builtin(Builtins::ArrayPush))); | 1611 Handle<Code>(Builtins::builtin(Builtins::ArrayPush))); |
1569 } | 1612 } |
1570 | 1613 |
1571 | 1614 |
1572 Genesis::Genesis(Handle<Object> global_object, | 1615 Genesis::Genesis(Handle<Object> global_object, |
1573 v8::Handle<v8::ObjectTemplate> global_template, | 1616 v8::Handle<v8::ObjectTemplate> global_template, |
1574 v8::ExtensionConfiguration* extensions) { | 1617 v8::ExtensionConfiguration* extensions) { |
1575 // Link this genesis object into the stacked genesis chain. This | 1618 // Link this genesis object into the stacked genesis chain. This |
1576 // must be done before any early exits because the destructor | 1619 // must be done before any early exits because the destructor |
1577 // will always do unlinking. | 1620 // will always do unlinking. |
1578 previous_ = current_; | 1621 Genesis* & current = v8_context()->bootstrapper_data_.private_data_.current_; |
1579 current_ = this; | 1622 previous_ = current; |
| 1623 current = this; |
1580 result_ = Handle<Context>::null(); | 1624 result_ = Handle<Context>::null(); |
1581 | 1625 |
1582 // If V8 isn't running and cannot be initialized, just return. | 1626 // If V8 isn't running and cannot be initialized, just return. |
1583 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; | 1627 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; |
1584 | 1628 |
1585 // Before creating the roots we must save the context and restore it | 1629 // Before creating the roots we must save the context and restore it |
1586 // on all function exits. | 1630 // on all function exits. |
1587 HandleScope scope; | 1631 HandleScope scope; |
1588 SaveContext context; | 1632 SaveContext context; |
1589 | 1633 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1625 | 1669 |
1626 | 1670 |
1627 // Called when the top-level V8 mutex is destroyed. | 1671 // Called when the top-level V8 mutex is destroyed. |
1628 void Bootstrapper::FreeThreadResources() { | 1672 void Bootstrapper::FreeThreadResources() { |
1629 ASSERT(Genesis::current() == NULL); | 1673 ASSERT(Genesis::current() == NULL); |
1630 } | 1674 } |
1631 | 1675 |
1632 | 1676 |
1633 // Reserve space for statics needing saving and restoring. | 1677 // Reserve space for statics needing saving and restoring. |
1634 int Genesis::ArchiveSpacePerThread() { | 1678 int Genesis::ArchiveSpacePerThread() { |
1635 return sizeof(current_); | 1679 return sizeof(v8_context()->bootstrapper_data_.private_data_.current_); |
1636 } | 1680 } |
1637 | 1681 |
1638 | 1682 |
1639 // Archive statics that are thread local. | 1683 // Archive statics that are thread local. |
1640 char* Genesis::ArchiveState(char* to) { | 1684 char* Genesis::ArchiveState(char* to) { |
1641 *reinterpret_cast<Genesis**>(to) = current_; | 1685 Genesis* & current = v8_context()->bootstrapper_data_.private_data_.current_; |
1642 current_ = NULL; | 1686 *reinterpret_cast<Genesis**>(to) = current; |
1643 return to + sizeof(current_); | 1687 current = NULL; |
| 1688 return to + sizeof(current); |
1644 } | 1689 } |
1645 | 1690 |
1646 | 1691 |
1647 // Restore statics that are thread local. | 1692 // Restore statics that are thread local. |
1648 char* Genesis::RestoreState(char* from) { | 1693 char* Genesis::RestoreState(char* from) { |
1649 current_ = *reinterpret_cast<Genesis**>(from); | 1694 Genesis* & current = v8_context()->bootstrapper_data_.private_data_.current_; |
1650 return from + sizeof(current_); | 1695 current = *reinterpret_cast<Genesis**>(from); |
| 1696 return from + sizeof(current); |
1651 } | 1697 } |
1652 | 1698 |
1653 } } // namespace v8::internal | 1699 } } // namespace v8::internal |
OLD | NEW |