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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 } | 185 } |
186 delete delete_these_arrays_on_tear_down; | 186 delete delete_these_arrays_on_tear_down; |
187 delete_these_arrays_on_tear_down = NULL; | 187 delete_these_arrays_on_tear_down = NULL; |
188 } | 188 } |
189 | 189 |
190 natives_cache.Initialize(false); // Yes, symmetrical | 190 natives_cache.Initialize(false); // Yes, symmetrical |
191 extensions_cache.Initialize(false); | 191 extensions_cache.Initialize(false); |
192 } | 192 } |
193 | 193 |
194 | 194 |
195 // Pending fixups are code positions that refer to builtin code | |
196 // objects that were not available at the time the code was generated. | |
197 // The pending list is processed whenever an environment has been | |
198 // created. | |
199 class PendingFixups : public AllStatic { | |
200 public: | |
201 static void Add(Code* code, MacroAssembler* masm); | |
202 static bool Process(Handle<JSBuiltinsObject> builtins); | |
203 | |
204 static void Iterate(ObjectVisitor* v); | |
205 | |
206 private: | |
207 static List<Object*> code_; | |
208 static List<const char*> name_; | |
209 static List<int> pc_; | |
210 static List<uint32_t> flags_; | |
211 | |
212 static void Clear(); | |
213 }; | |
214 | |
215 | |
216 List<Object*> PendingFixups::code_(0); | |
217 List<const char*> PendingFixups::name_(0); | |
218 List<int> PendingFixups::pc_(0); | |
219 List<uint32_t> PendingFixups::flags_(0); | |
220 | |
221 | |
222 void PendingFixups::Add(Code* code, MacroAssembler* masm) { | |
223 // Note this code is not only called during bootstrapping. | |
224 List<MacroAssembler::Unresolved>* unresolved = masm->unresolved(); | |
225 int n = unresolved->length(); | |
226 for (int i = 0; i < n; i++) { | |
227 const char* name = unresolved->at(i).name; | |
228 code_.Add(code); | |
229 name_.Add(name); | |
230 pc_.Add(unresolved->at(i).pc); | |
231 flags_.Add(unresolved->at(i).flags); | |
232 LOG(StringEvent("unresolved", name)); | |
233 } | |
234 } | |
235 | |
236 | |
237 bool PendingFixups::Process(Handle<JSBuiltinsObject> builtins) { | |
238 HandleScope scope; | |
239 // NOTE: Extra fixups may be added to the list during the iteration | |
240 // due to lazy compilation of functions during the processing. Do not | |
241 // cache the result of getting the length of the code list. | |
242 for (int i = 0; i < code_.length(); i++) { | |
243 const char* name = name_[i]; | |
244 uint32_t flags = flags_[i]; | |
245 Handle<String> symbol = Factory::LookupAsciiSymbol(name); | |
246 Object* o = builtins->GetProperty(*symbol); | |
247 #ifdef DEBUG | |
248 if (!o->IsJSFunction()) { | |
249 V8_Fatal(__FILE__, __LINE__, "Cannot resolve call to builtin %s", name); | |
250 } | |
251 #endif | |
252 Handle<SharedFunctionInfo> shared(JSFunction::cast(o)->shared()); | |
253 // Make sure the number of parameters match the formal parameter count. | |
254 int argc = Bootstrapper::FixupFlagsArgumentsCount::decode(flags); | |
255 USE(argc); | |
256 ASSERT(shared->formal_parameter_count() == argc); | |
257 // Do lazy compilation if necessary and check for stack overflows. | |
258 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) { | |
259 Clear(); | |
260 return false; | |
261 } | |
262 Code* code = Code::cast(code_[i]); | |
263 Address pc = code->instruction_start() + pc_[i]; | |
264 RelocInfo target(pc, RelocInfo::CODE_TARGET, 0); | |
265 bool use_code_object = Bootstrapper::FixupFlagsUseCodeObject::decode(flags); | |
266 if (use_code_object) { | |
267 target.set_target_object(shared->code()); | |
268 } else { | |
269 target.set_target_address(shared->code()->instruction_start()); | |
270 } | |
271 LOG(StringEvent("resolved", name)); | |
272 } | |
273 Clear(); | |
274 | |
275 // TODO(1240818): We should probably try to avoid doing this for all | |
276 // the V8 builtin JS files. It should only happen after running | |
277 // runtime.js - just like there shouldn't be any fixups left after | |
278 // that. | |
279 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { | |
280 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); | |
281 Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id)); | |
282 JSFunction* function = JSFunction::cast(builtins->GetProperty(*name)); | |
283 builtins->set_javascript_builtin(id, function); | |
284 } | |
285 | |
286 return true; | |
287 } | |
288 | |
289 | |
290 void PendingFixups::Clear() { | |
291 code_.Clear(); | |
292 name_.Clear(); | |
293 pc_.Clear(); | |
294 flags_.Clear(); | |
295 } | |
296 | |
297 | |
298 void PendingFixups::Iterate(ObjectVisitor* v) { | |
299 if (!code_.is_empty()) { | |
300 v->VisitPointers(&code_[0], &code_[0] + code_.length()); | |
301 } | |
302 } | |
303 | |
304 | |
305 class Genesis BASE_EMBEDDED { | 195 class Genesis BASE_EMBEDDED { |
306 public: | 196 public: |
307 Genesis(Handle<Object> global_object, | 197 Genesis(Handle<Object> global_object, |
308 v8::Handle<v8::ObjectTemplate> global_template, | 198 v8::Handle<v8::ObjectTemplate> global_template, |
309 v8::ExtensionConfiguration* extensions); | 199 v8::ExtensionConfiguration* extensions); |
310 ~Genesis(); | 200 ~Genesis(); |
311 | 201 |
312 Handle<Context> result() { return result_; } | 202 Handle<Context> result() { return result_; } |
313 | 203 |
314 Genesis* previous() { return previous_; } | 204 Genesis* previous() { return previous_; } |
(...skipping 16 matching lines...) Expand all Loading... |
331 Handle<Context> global_context() { return global_context_; } | 221 Handle<Context> global_context() { return global_context_; } |
332 | 222 |
333 void CreateRoots(v8::Handle<v8::ObjectTemplate> global_template, | 223 void CreateRoots(v8::Handle<v8::ObjectTemplate> global_template, |
334 Handle<Object> global_object); | 224 Handle<Object> global_object); |
335 void InstallNativeFunctions(); | 225 void InstallNativeFunctions(); |
336 bool InstallNatives(); | 226 bool InstallNatives(); |
337 bool InstallExtensions(v8::ExtensionConfiguration* extensions); | 227 bool InstallExtensions(v8::ExtensionConfiguration* extensions); |
338 bool InstallExtension(const char* name); | 228 bool InstallExtension(const char* name); |
339 bool InstallExtension(v8::RegisteredExtension* current); | 229 bool InstallExtension(v8::RegisteredExtension* current); |
340 bool InstallSpecialObjects(); | 230 bool InstallSpecialObjects(); |
| 231 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); |
341 bool ConfigureApiObject(Handle<JSObject> object, | 232 bool ConfigureApiObject(Handle<JSObject> object, |
342 Handle<ObjectTemplateInfo> object_template); | 233 Handle<ObjectTemplateInfo> object_template); |
343 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); | 234 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); |
344 | 235 |
345 // Migrates all properties from the 'from' object to the 'to' | 236 // Migrates all properties from the 'from' object to the 'to' |
346 // object and overrides the prototype in 'to' with the one from | 237 // object and overrides the prototype in 'to' with the one from |
347 // 'from'. | 238 // 'from'. |
348 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); | 239 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
349 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); | 240 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); |
350 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); | 241 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); |
(...skipping 21 matching lines...) Expand all Loading... |
372 }; | 263 }; |
373 | 264 |
374 Genesis* Genesis::current_ = NULL; | 265 Genesis* Genesis::current_ = NULL; |
375 | 266 |
376 | 267 |
377 void Bootstrapper::Iterate(ObjectVisitor* v) { | 268 void Bootstrapper::Iterate(ObjectVisitor* v) { |
378 natives_cache.Iterate(v); | 269 natives_cache.Iterate(v); |
379 v->Synchronize("NativesCache"); | 270 v->Synchronize("NativesCache"); |
380 extensions_cache.Iterate(v); | 271 extensions_cache.Iterate(v); |
381 v->Synchronize("Extensions"); | 272 v->Synchronize("Extensions"); |
382 PendingFixups::Iterate(v); | |
383 v->Synchronize("PendingFixups"); | |
384 } | |
385 | |
386 | |
387 // While setting up the environment, we collect code positions that | |
388 // need to be patched before we can run any code in the environment. | |
389 void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) { | |
390 PendingFixups::Add(code, masm); | |
391 } | 273 } |
392 | 274 |
393 | 275 |
394 bool Bootstrapper::IsActive() { | 276 bool Bootstrapper::IsActive() { |
395 return Genesis::current() != NULL; | 277 return Genesis::current() != NULL; |
396 } | 278 } |
397 | 279 |
398 | 280 |
399 Handle<Context> Bootstrapper::CreateEnvironment( | 281 Handle<Context> Bootstrapper::CreateEnvironment( |
400 Handle<Object> global_object, | 282 Handle<Object> global_object, |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 // Call function using either the runtime object or the global | 843 // Call function using either the runtime object or the global |
962 // object as the receiver. Provide no parameters. | 844 // object as the receiver. Provide no parameters. |
963 Handle<Object> receiver = | 845 Handle<Object> receiver = |
964 Handle<Object>(use_runtime_context | 846 Handle<Object>(use_runtime_context |
965 ? Top::context()->builtins() | 847 ? Top::context()->builtins() |
966 : Top::context()->global()); | 848 : Top::context()->global()); |
967 bool has_pending_exception; | 849 bool has_pending_exception; |
968 Handle<Object> result = | 850 Handle<Object> result = |
969 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception); | 851 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception); |
970 if (has_pending_exception) return false; | 852 if (has_pending_exception) return false; |
971 return PendingFixups::Process( | 853 return true; |
972 Handle<JSBuiltinsObject>(Top::context()->builtins())); | |
973 } | 854 } |
974 | 855 |
975 | 856 |
976 #define INSTALL_NATIVE(Type, name, var) \ | 857 #define INSTALL_NATIVE(Type, name, var) \ |
977 Handle<String> var##_name = Factory::LookupAsciiSymbol(name); \ | 858 Handle<String> var##_name = Factory::LookupAsciiSymbol(name); \ |
978 global_context()->set_##var(Type::cast(global_context()-> \ | 859 global_context()->set_##var(Type::cast(global_context()-> \ |
979 builtins()-> \ | 860 builtins()-> \ |
980 GetProperty(*var##_name))); | 861 GetProperty(*var##_name))); |
981 | 862 |
982 void Genesis::InstallNativeFunctions() { | 863 void Genesis::InstallNativeFunctions() { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 1050 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
1170 global_context()->set_empty_script(*script); | 1051 global_context()->set_empty_script(*script); |
1171 } | 1052 } |
1172 | 1053 |
1173 if (FLAG_natives_file == NULL) { | 1054 if (FLAG_natives_file == NULL) { |
1174 // Without natives file, install default natives. | 1055 // Without natives file, install default natives. |
1175 for (int i = Natives::GetDelayCount(); | 1056 for (int i = Natives::GetDelayCount(); |
1176 i < Natives::GetBuiltinsCount(); | 1057 i < Natives::GetBuiltinsCount(); |
1177 i++) { | 1058 i++) { |
1178 if (!CompileBuiltin(i)) return false; | 1059 if (!CompileBuiltin(i)) return false; |
| 1060 // TODO(ager): We really only need to install the JS builtin |
| 1061 // functions on the builtins object after compiling and running |
| 1062 // runtime.js. |
| 1063 if (!InstallJSBuiltins(builtins)) return false; |
1179 } | 1064 } |
1180 | 1065 |
1181 // Setup natives with lazy loading. | 1066 // Setup natives with lazy loading. |
1182 SetupLazy(Handle<JSFunction>(global_context()->date_function()), | 1067 SetupLazy(Handle<JSFunction>(global_context()->date_function()), |
1183 Natives::GetIndex("date"), | 1068 Natives::GetIndex("date"), |
1184 Top::global_context(), | 1069 Top::global_context(), |
1185 Handle<Context>(Top::context()->runtime_context())); | 1070 Handle<Context>(Top::context()->runtime_context())); |
1186 SetupLazy(Handle<JSFunction>(global_context()->regexp_function()), | 1071 SetupLazy(Handle<JSFunction>(global_context()->regexp_function()), |
1187 Natives::GetIndex("regexp"), | 1072 Natives::GetIndex("regexp"), |
1188 Top::global_context(), | 1073 Top::global_context(), |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1370 false); | 1255 false); |
1371 ASSERT(Top::has_pending_exception() != result); | 1256 ASSERT(Top::has_pending_exception() != result); |
1372 if (!result) { | 1257 if (!result) { |
1373 Top::clear_pending_exception(); | 1258 Top::clear_pending_exception(); |
1374 } | 1259 } |
1375 current->set_state(v8::INSTALLED); | 1260 current->set_state(v8::INSTALLED); |
1376 return result; | 1261 return result; |
1377 } | 1262 } |
1378 | 1263 |
1379 | 1264 |
| 1265 bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) { |
| 1266 HandleScope scope; |
| 1267 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { |
| 1268 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); |
| 1269 Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id)); |
| 1270 Handle<JSFunction> function |
| 1271 = Handle<JSFunction>(JSFunction::cast(builtins->GetProperty(*name))); |
| 1272 builtins->set_javascript_builtin(id, *function); |
| 1273 Handle<SharedFunctionInfo> shared |
| 1274 = Handle<SharedFunctionInfo>(function->shared()); |
| 1275 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; |
| 1276 } |
| 1277 return true; |
| 1278 } |
| 1279 |
| 1280 |
1380 bool Genesis::ConfigureGlobalObjects( | 1281 bool Genesis::ConfigureGlobalObjects( |
1381 v8::Handle<v8::ObjectTemplate> global_proxy_template) { | 1282 v8::Handle<v8::ObjectTemplate> global_proxy_template) { |
1382 Handle<JSObject> global_proxy( | 1283 Handle<JSObject> global_proxy( |
1383 JSObject::cast(global_context()->global_proxy())); | 1284 JSObject::cast(global_context()->global_proxy())); |
1384 Handle<JSObject> js_global(JSObject::cast(global_context()->global())); | 1285 Handle<JSObject> js_global(JSObject::cast(global_context()->global())); |
1385 | 1286 |
1386 if (!global_proxy_template.IsEmpty()) { | 1287 if (!global_proxy_template.IsEmpty()) { |
1387 // Configure the global proxy object. | 1288 // Configure the global proxy object. |
1388 Handle<ObjectTemplateInfo> proxy_data = | 1289 Handle<ObjectTemplateInfo> proxy_data = |
1389 v8::Utils::OpenHandle(*global_proxy_template); | 1290 v8::Utils::OpenHandle(*global_proxy_template); |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1669 } | 1570 } |
1670 | 1571 |
1671 | 1572 |
1672 // Restore statics that are thread local. | 1573 // Restore statics that are thread local. |
1673 char* Genesis::RestoreState(char* from) { | 1574 char* Genesis::RestoreState(char* from) { |
1674 current_ = *reinterpret_cast<Genesis**>(from); | 1575 current_ = *reinterpret_cast<Genesis**>(from); |
1675 return from + sizeof(current_); | 1576 return from + sizeof(current_); |
1676 } | 1577 } |
1677 | 1578 |
1678 } } // namespace v8::internal | 1579 } } // namespace v8::internal |
OLD | NEW |