| 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); | |
| 95 static SourceCodeCache extensions_cache(Script::TYPE_EXTENSION); | 94 static SourceCodeCache extensions_cache(Script::TYPE_EXTENSION); |
| 96 // This is for delete, not delete[]. | 95 // This is for delete, not delete[]. |
| 97 static List<char*>* delete_these_non_arrays_on_tear_down = NULL; | 96 static List<char*>* delete_these_non_arrays_on_tear_down = NULL; |
| 98 // This is for delete[] | 97 // This is for delete[] |
| 99 static List<char*>* delete_these_arrays_on_tear_down = NULL; | 98 static List<char*>* delete_these_arrays_on_tear_down = NULL; |
| 100 | 99 |
| 101 | 100 |
| 102 NativesExternalStringResource::NativesExternalStringResource(const char* source) | 101 NativesExternalStringResource::NativesExternalStringResource(const char* source) |
| 103 : data_(source), length_(StrLength(source)) { | 102 : data_(source), length_(StrLength(source)) { |
| 104 if (delete_these_non_arrays_on_tear_down == NULL) { | 103 if (delete_these_non_arrays_on_tear_down == NULL) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 127 Handle<String> source_code = | 126 Handle<String> source_code = |
| 128 Factory::NewStringFromAscii(Natives::GetScriptSource(index)); | 127 Factory::NewStringFromAscii(Natives::GetScriptSource(index)); |
| 129 Heap::natives_source_cache()->set(index, *source_code); | 128 Heap::natives_source_cache()->set(index, *source_code); |
| 130 } | 129 } |
| 131 } | 130 } |
| 132 Handle<Object> cached_source(Heap::natives_source_cache()->get(index)); | 131 Handle<Object> cached_source(Heap::natives_source_cache()->get(index)); |
| 133 return Handle<String>::cast(cached_source); | 132 return Handle<String>::cast(cached_source); |
| 134 } | 133 } |
| 135 | 134 |
| 136 | 135 |
| 137 bool Bootstrapper::NativesCacheLookup(Vector<const char> name, | |
| 138 Handle<JSFunction>* handle) { | |
| 139 return natives_cache.Lookup(name, handle); | |
| 140 } | |
| 141 | |
| 142 | |
| 143 void Bootstrapper::NativesCacheAdd(Vector<const char> name, | |
| 144 Handle<JSFunction> fun) { | |
| 145 natives_cache.Add(name, fun); | |
| 146 } | |
| 147 | |
| 148 | |
| 149 void Bootstrapper::Initialize(bool create_heap_objects) { | 136 void Bootstrapper::Initialize(bool create_heap_objects) { |
| 150 natives_cache.Initialize(create_heap_objects); | |
| 151 extensions_cache.Initialize(create_heap_objects); | 137 extensions_cache.Initialize(create_heap_objects); |
| 152 } | 138 } |
| 153 | 139 |
| 154 | 140 |
| 155 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { | 141 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { |
| 156 char* memory = new char[bytes]; | 142 char* memory = new char[bytes]; |
| 157 if (memory != NULL) { | 143 if (memory != NULL) { |
| 158 if (delete_these_arrays_on_tear_down == NULL) { | 144 if (delete_these_arrays_on_tear_down == NULL) { |
| 159 delete_these_arrays_on_tear_down = new List<char*>(2); | 145 delete_these_arrays_on_tear_down = new List<char*>(2); |
| 160 } | 146 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 180 int len = delete_these_arrays_on_tear_down->length(); | 166 int len = delete_these_arrays_on_tear_down->length(); |
| 181 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations. | 167 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations. |
| 182 for (int i = 0; i < len; i++) { | 168 for (int i = 0; i < len; i++) { |
| 183 delete[] delete_these_arrays_on_tear_down->at(i); | 169 delete[] delete_these_arrays_on_tear_down->at(i); |
| 184 delete_these_arrays_on_tear_down->at(i) = NULL; | 170 delete_these_arrays_on_tear_down->at(i) = NULL; |
| 185 } | 171 } |
| 186 delete delete_these_arrays_on_tear_down; | 172 delete delete_these_arrays_on_tear_down; |
| 187 delete_these_arrays_on_tear_down = NULL; | 173 delete_these_arrays_on_tear_down = NULL; |
| 188 } | 174 } |
| 189 | 175 |
| 190 natives_cache.Initialize(false); // Yes, symmetrical | 176 extensions_cache.Initialize(false); // Yes, symmetrical |
| 191 extensions_cache.Initialize(false); | |
| 192 } | 177 } |
| 193 | 178 |
| 194 | 179 |
| 195 // Pending fixups are code positions that refer to builtin code | 180 // Pending fixups are code positions that refer to builtin code |
| 196 // objects that were not available at the time the code was generated. | 181 // objects that were not available at the time the code was generated. |
| 197 // The pending list is processed whenever an environment has been | 182 // The pending list is processed whenever an environment has been |
| 198 // created. | 183 // created. |
| 199 class PendingFixups : public AllStatic { | 184 class PendingFixups : public AllStatic { |
| 200 public: | 185 public: |
| 201 static void Add(Code* code, MacroAssembler* masm); | 186 static void Add(Code* code, MacroAssembler* masm); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 v8::Extension* extension, | 353 v8::Extension* extension, |
| 369 bool use_runtime_context); | 354 bool use_runtime_context); |
| 370 | 355 |
| 371 Handle<Context> result_; | 356 Handle<Context> result_; |
| 372 }; | 357 }; |
| 373 | 358 |
| 374 Genesis* Genesis::current_ = NULL; | 359 Genesis* Genesis::current_ = NULL; |
| 375 | 360 |
| 376 | 361 |
| 377 void Bootstrapper::Iterate(ObjectVisitor* v) { | 362 void Bootstrapper::Iterate(ObjectVisitor* v) { |
| 378 natives_cache.Iterate(v); | |
| 379 v->Synchronize("NativesCache"); | |
| 380 extensions_cache.Iterate(v); | 363 extensions_cache.Iterate(v); |
| 381 v->Synchronize("Extensions"); | 364 v->Synchronize("Extensions"); |
| 382 PendingFixups::Iterate(v); | 365 PendingFixups::Iterate(v); |
| 383 v->Synchronize("PendingFixups"); | 366 v->Synchronize("PendingFixups"); |
| 384 } | 367 } |
| 385 | 368 |
| 386 | 369 |
| 387 // While setting up the environment, we collect code positions that | 370 // While setting up the environment, we collect code positions that |
| 388 // need to be patched before we can run any code in the environment. | 371 // need to be patched before we can run any code in the environment. |
| 389 void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) { | 372 void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) { |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 return CompileNative(name, source_code); | 894 return CompileNative(name, source_code); |
| 912 } | 895 } |
| 913 | 896 |
| 914 | 897 |
| 915 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) { | 898 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) { |
| 916 HandleScope scope; | 899 HandleScope scope; |
| 917 #ifdef ENABLE_DEBUGGER_SUPPORT | 900 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 918 Debugger::set_compiling_natives(true); | 901 Debugger::set_compiling_natives(true); |
| 919 #endif | 902 #endif |
| 920 bool result = | 903 bool result = |
| 921 CompileScriptCached(name, source, &natives_cache, NULL, true); | 904 CompileScriptCached(name, source, NULL, NULL, true); |
| 922 ASSERT(Top::has_pending_exception() != result); | 905 ASSERT(Top::has_pending_exception() != result); |
| 923 if (!result) Top::clear_pending_exception(); | 906 if (!result) Top::clear_pending_exception(); |
| 924 #ifdef ENABLE_DEBUGGER_SUPPORT | 907 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 925 Debugger::set_compiling_natives(false); | 908 Debugger::set_compiling_natives(false); |
| 926 #endif | 909 #endif |
| 927 return result; | 910 return result; |
| 928 } | 911 } |
| 929 | 912 |
| 930 | 913 |
| 931 bool Genesis::CompileScriptCached(Vector<const char> name, | 914 bool Genesis::CompileScriptCached(Vector<const char> name, |
| 932 Handle<String> source, | 915 Handle<String> source, |
| 933 SourceCodeCache* cache, | 916 SourceCodeCache* cache, |
| 934 v8::Extension* extension, | 917 v8::Extension* extension, |
| 935 bool use_runtime_context) { | 918 bool use_runtime_context) { |
| 936 HandleScope scope; | 919 HandleScope scope; |
| 937 Handle<JSFunction> boilerplate; | 920 Handle<JSFunction> boilerplate; |
| 938 | 921 |
| 939 // If we can't find the function in the cache, we compile a new | 922 // If we can't find the function in the cache, we compile a new |
| 940 // function and insert it into the cache. | 923 // function and insert it into the cache. |
| 941 if (!cache->Lookup(name, &boilerplate)) { | 924 if (cache == NULL || !cache->Lookup(name, &boilerplate)) { |
| 942 ASSERT(source->IsAsciiRepresentation()); | 925 ASSERT(source->IsAsciiRepresentation()); |
| 943 Handle<String> script_name = Factory::NewStringFromUtf8(name); | 926 Handle<String> script_name = Factory::NewStringFromUtf8(name); |
| 944 boilerplate = | 927 boilerplate = Compiler::Compile( |
| 945 Compiler::Compile(source, script_name, 0, 0, extension, NULL); | 928 source, |
| 929 script_name, |
| 930 0, |
| 931 0, |
| 932 extension, |
| 933 NULL, |
| 934 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE); |
| 946 if (boilerplate.is_null()) return false; | 935 if (boilerplate.is_null()) return false; |
| 947 cache->Add(name, boilerplate); | 936 if (cache != NULL) cache->Add(name, boilerplate); |
| 948 } | 937 } |
| 949 | 938 |
| 950 // Setup the function context. Conceptually, we should clone the | 939 // Setup the function context. Conceptually, we should clone the |
| 951 // function before overwriting the context but since we're in a | 940 // function before overwriting the context but since we're in a |
| 952 // single-threaded environment it is not strictly necessary. | 941 // single-threaded environment it is not strictly necessary. |
| 953 ASSERT(Top::context()->IsGlobalContext()); | 942 ASSERT(Top::context()->IsGlobalContext()); |
| 954 Handle<Context> context = | 943 Handle<Context> context = |
| 955 Handle<Context>(use_runtime_context | 944 Handle<Context>(use_runtime_context |
| 956 ? Top::context()->runtime_context() | 945 ? Top::context()->runtime_context() |
| 957 : Top::context()); | 946 : Top::context()); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 | 1152 |
| 1164 Handle<Map> script_map = Handle<Map>(script_fun->initial_map()); | 1153 Handle<Map> script_map = Handle<Map>(script_fun->initial_map()); |
| 1165 script_map->set_instance_descriptors(*script_descriptors); | 1154 script_map->set_instance_descriptors(*script_descriptors); |
| 1166 | 1155 |
| 1167 // Allocate the empty script. | 1156 // Allocate the empty script. |
| 1168 Handle<Script> script = Factory::NewScript(Factory::empty_string()); | 1157 Handle<Script> script = Factory::NewScript(Factory::empty_string()); |
| 1169 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 1158 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
| 1170 global_context()->set_empty_script(*script); | 1159 global_context()->set_empty_script(*script); |
| 1171 } | 1160 } |
| 1172 | 1161 |
| 1173 if (FLAG_natives_file == NULL) { | 1162 // Install natives. |
| 1174 // Without natives file, install default natives. | 1163 for (int i = Natives::GetDebuggerCount(); |
| 1175 for (int i = Natives::GetDelayCount(); | 1164 i < Natives::GetBuiltinsCount(); |
| 1176 i < Natives::GetBuiltinsCount(); | 1165 i++) { |
| 1177 i++) { | 1166 Vector<const char> name = Natives::GetScriptName(i); |
| 1178 if (!CompileBuiltin(i)) return false; | 1167 if (!CompileBuiltin(i)) return false; |
| 1179 } | |
| 1180 | |
| 1181 // Setup natives with lazy loading. | |
| 1182 SetupLazy(Handle<JSFunction>(global_context()->date_function()), | |
| 1183 Natives::GetIndex("date"), | |
| 1184 Top::global_context(), | |
| 1185 Handle<Context>(Top::context()->runtime_context())); | |
| 1186 SetupLazy(Handle<JSFunction>(global_context()->regexp_function()), | |
| 1187 Natives::GetIndex("regexp"), | |
| 1188 Top::global_context(), | |
| 1189 Handle<Context>(Top::context()->runtime_context())); | |
| 1190 SetupLazy(Handle<JSObject>(global_context()->json_object()), | |
| 1191 Natives::GetIndex("json"), | |
| 1192 Top::global_context(), | |
| 1193 Handle<Context>(Top::context()->runtime_context())); | |
| 1194 | |
| 1195 } else if (strlen(FLAG_natives_file) != 0) { | |
| 1196 // Otherwise install natives from natives file if file exists and | |
| 1197 // compiles. | |
| 1198 bool exists; | |
| 1199 Vector<const char> source = ReadFile(FLAG_natives_file, &exists); | |
| 1200 Handle<String> source_string = Factory::NewStringFromAscii(source); | |
| 1201 if (source.is_empty()) return false; | |
| 1202 bool result = CompileNative(CStrVector(FLAG_natives_file), source_string); | |
| 1203 if (!result) return false; | |
| 1204 | |
| 1205 } else { | |
| 1206 // Empty natives file name - do not install any natives. | |
| 1207 PrintF("Warning: Running without installed natives!\n"); | |
| 1208 return true; | |
| 1209 } | 1168 } |
| 1210 | 1169 |
| 1211 InstallNativeFunctions(); | 1170 InstallNativeFunctions(); |
| 1212 | 1171 |
| 1213 // Install Function.prototype.call and apply. | 1172 // Install Function.prototype.call and apply. |
| 1214 { Handle<String> key = Factory::function_class_symbol(); | 1173 { Handle<String> key = Factory::function_class_symbol(); |
| 1215 Handle<JSFunction> function = | 1174 Handle<JSFunction> function = |
| 1216 Handle<JSFunction>::cast(GetProperty(Top::global(), key)); | 1175 Handle<JSFunction>::cast(GetProperty(Top::global(), key)); |
| 1217 Handle<JSObject> proto = | 1176 Handle<JSObject> proto = |
| 1218 Handle<JSObject>(JSObject::cast(function->instance_prototype())); | 1177 Handle<JSObject>(JSObject::cast(function->instance_prototype())); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1239 apply->shared()->set_formal_parameter_count(2); | 1198 apply->shared()->set_formal_parameter_count(2); |
| 1240 | 1199 |
| 1241 // Set the lengths for the functions to satisfy ECMA-262. | 1200 // Set the lengths for the functions to satisfy ECMA-262. |
| 1242 call->shared()->set_length(1); | 1201 call->shared()->set_length(1); |
| 1243 apply->shared()->set_length(2); | 1202 apply->shared()->set_length(2); |
| 1244 } | 1203 } |
| 1245 | 1204 |
| 1246 #ifdef DEBUG | 1205 #ifdef DEBUG |
| 1247 builtins->Verify(); | 1206 builtins->Verify(); |
| 1248 #endif | 1207 #endif |
| 1208 |
| 1249 return true; | 1209 return true; |
| 1250 } | 1210 } |
| 1251 | 1211 |
| 1252 | 1212 |
| 1253 bool Genesis::InstallSpecialObjects() { | 1213 bool Genesis::InstallSpecialObjects() { |
| 1254 HandleScope scope; | 1214 HandleScope scope; |
| 1255 Handle<JSGlobalObject> js_global( | 1215 Handle<JSGlobalObject> js_global( |
| 1256 JSGlobalObject::cast(global_context()->global())); | 1216 JSGlobalObject::cast(global_context()->global())); |
| 1257 // Expose the natives in global if a name for it is specified. | 1217 // Expose the natives in global if a name for it is specified. |
| 1258 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { | 1218 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 } | 1629 } |
| 1670 | 1630 |
| 1671 | 1631 |
| 1672 // Restore statics that are thread local. | 1632 // Restore statics that are thread local. |
| 1673 char* Genesis::RestoreState(char* from) { | 1633 char* Genesis::RestoreState(char* from) { |
| 1674 current_ = *reinterpret_cast<Genesis**>(from); | 1634 current_ = *reinterpret_cast<Genesis**>(from); |
| 1675 return from + sizeof(current_); | 1635 return from + sizeof(current_); |
| 1676 } | 1636 } |
| 1677 | 1637 |
| 1678 } } // namespace v8::internal | 1638 } } // namespace v8::internal |
| OLD | NEW |