📄 bootstrapper.cc.svn-base
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "accessors.h"#include "api.h"#include "bootstrapper.h"#include "compiler.h"#include "debug.h"#include "execution.h"#include "global-handles.h"#include "macro-assembler.h"#include "natives.h"namespace v8 { namespace internal {// A SourceCodeCache uses a FixedArray to store pairs of// (AsciiString*, JSFunction*), mapping names of native code files// (runtime.js, etc.) to precompiled functions. Instead of mapping// names to functions it might make sense to let the JS2C tool// generate an index for each native JS file.class SourceCodeCache BASE_EMBEDDED { public: explicit SourceCodeCache(ScriptType type): type_(type) { } void Initialize(bool create_heap_objects) { if (create_heap_objects) { cache_ = Heap::empty_fixed_array(); } else { cache_ = NULL; } } void Iterate(ObjectVisitor* v) { v->VisitPointer(reinterpret_cast<Object**>(&cache_)); } bool Lookup(Vector<const char> name, Handle<JSFunction>* handle) { for (int i = 0; i < cache_->length(); i+=2) { AsciiString* str = AsciiString::cast(cache_->get(i)); if (str->IsEqualTo(name)) { *handle = Handle<JSFunction>(JSFunction::cast(cache_->get(i + 1))); return true; } } return false; } void Add(Vector<const char> name, Handle<JSFunction> fun) { ASSERT(fun->IsBoilerplate()); HandleScope scope; int length = cache_->length(); Handle<FixedArray> new_array = Factory::NewFixedArray(length + 2, TENURED); cache_->CopyTo(0, *new_array, 0, cache_->length()); cache_ = *new_array; Handle<String> str = Factory::NewStringFromAscii(name, TENURED); cache_->set(length, *str); cache_->set(length + 1, *fun); Script::cast(fun->shared()->script())->set_type(Smi::FromInt(type_)); } private: ScriptType type_; FixedArray* cache_; DISALLOW_COPY_AND_ASSIGN(SourceCodeCache);};static SourceCodeCache natives_cache(SCRIPT_TYPE_NATIVE);static SourceCodeCache extensions_cache(SCRIPT_TYPE_EXTENSION);Handle<String> Bootstrapper::NativesSourceLookup(int index) { ASSERT(0 <= index && index < Natives::GetBuiltinsCount()); if (Heap::natives_source_cache()->get(index)->IsUndefined()) { Handle<String> source_code = Factory::NewStringFromAscii(Natives::GetScriptSource(index)); Heap::natives_source_cache()->set(index, *source_code); } Handle<Object> cached_source(Heap::natives_source_cache()->get(index)); return Handle<String>::cast(cached_source);}bool Bootstrapper::NativesCacheLookup(Vector<const char> name, Handle<JSFunction>* handle) { return natives_cache.Lookup(name, handle);}void Bootstrapper::NativesCacheAdd(Vector<const char> name, Handle<JSFunction> fun) { natives_cache.Add(name, fun);}void Bootstrapper::Initialize(bool create_heap_objects) { natives_cache.Initialize(create_heap_objects); extensions_cache.Initialize(create_heap_objects);}void Bootstrapper::TearDown() { natives_cache.Initialize(false); // Yes, symmetrical extensions_cache.Initialize(false);}// Pending fixups are code positions that have refer to builtin code// objects that were not available at the time the code was generated.// The pending list is processed whenever an environment has been// created.class PendingFixups : public AllStatic { public: static void Add(Code* code, MacroAssembler* masm); static bool Process(Handle<JSBuiltinsObject> builtins); static void Iterate(ObjectVisitor* v); private: static List<Object*> code_; static List<const char*> name_; static List<int> pc_; static List<uint32_t> flags_; static void Clear();};List<Object*> PendingFixups::code_(0);List<const char*> PendingFixups::name_(0);List<int> PendingFixups::pc_(0);List<uint32_t> PendingFixups::flags_(0);void PendingFixups::Add(Code* code, MacroAssembler* masm) { // Note this code is not only called during bootstrapping. List<MacroAssembler::Unresolved>* unresolved = masm->unresolved(); int n = unresolved->length(); for (int i = 0; i < n; i++) { const char* name = unresolved->at(i).name; code_.Add(code); name_.Add(name); pc_.Add(unresolved->at(i).pc); flags_.Add(unresolved->at(i).flags); LOG(StringEvent("unresolved", name)); }}bool PendingFixups::Process(Handle<JSBuiltinsObject> builtins) { HandleScope scope; // NOTE: Extra fixups may be added to the list during the iteration // due to lazy compilation of functions during the processing. Do not // cache the result of getting the length of the code list. for (int i = 0; i < code_.length(); i++) { const char* name = name_[i]; uint32_t flags = flags_[i]; Handle<String> symbol = Factory::LookupAsciiSymbol(name); Object* o = builtins->GetProperty(*symbol);#ifdef DEBUG if (!o->IsJSFunction()) { V8_Fatal(__FILE__, __LINE__, "Cannot resolve call to builtin %s", name); }#endif Handle<JSFunction> f = Handle<JSFunction>(JSFunction::cast(o)); // Make sure the number of parameters match the formal parameter count. int argc = Bootstrapper::FixupFlagsArgumentsCount::decode(flags); USE(argc); ASSERT(f->shared()->formal_parameter_count() == argc); if (!f->is_compiled()) { // Do lazy compilation and check for stack overflows. if (!CompileLazy(f, CLEAR_EXCEPTION)) { Clear(); return false; } } Code* code = Code::cast(code_[i]); Address pc = code->instruction_start() + pc_[i]; bool is_pc_relative = Bootstrapper::FixupFlagsIsPCRelative::decode(flags); if (is_pc_relative) { Assembler::set_target_address_at(pc, f->code()->instruction_start()); } else { *reinterpret_cast<Object**>(pc) = f->code(); } LOG(StringEvent("resolved", name)); } Clear(); // TODO(1240818): We should probably try to avoid doing this for all // the V8 builtin JS files. It should only happen after running // runtime.js - just like there shouldn't be any fixups left after // that. for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id)); JSFunction* function = JSFunction::cast(builtins->GetProperty(*name)); builtins->set_javascript_builtin(id, function); } return true;}void PendingFixups::Clear() { code_.Clear(); name_.Clear(); pc_.Clear(); flags_.Clear();}void PendingFixups::Iterate(ObjectVisitor* v) { if (!code_.is_empty()) { v->VisitPointers(&code_[0], &code_[0] + code_.length()); }}class Genesis BASE_EMBEDDED { public: Genesis(Handle<Object> global_object, v8::Handle<v8::ObjectTemplate> global_template, v8::ExtensionConfiguration* extensions); ~Genesis(); Handle<Context> result() { return result_; } Genesis* previous() { return previous_; } static Genesis* current() { return current_; } private: Handle<Context> global_context_; // There may be more than one active genesis object: When GC is // triggered during environment creation there may be weak handle // processing callbacks which may create new environments. Genesis* previous_; static Genesis* current_; Handle<Context> global_context() { return global_context_; } void CreateRoots(v8::Handle<v8::ObjectTemplate> global_template, Handle<Object> global_object); void InstallNativeFunctions(); bool InstallNatives(); bool InstallExtensions(v8::ExtensionConfiguration* extensions); bool InstallExtension(const char* name); bool InstallExtension(v8::RegisteredExtension* current); bool InstallSpecialObjects(); bool ConfigureGlobalObject(v8::Handle<v8::ObjectTemplate> global_template); // Migrates all properties from the 'from' object to the 'to' // object and overrides the prototype in 'to' with the one from // 'from'. void TransferObject(Handle<JSObject> from, Handle<JSObject> to); void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( bool make_prototype_read_only, bool make_prototype_enumerable = false); void MakeFunctionInstancePrototypeWritable(); void AddSpecialFunction(Handle<JSObject> prototype, const char* name, Handle<Code> code); void BuildSpecialFunctionTable(); static bool CompileBuiltin(int index); static bool CompileNative(Vector<const char> name, Handle<String> source); static bool CompileScriptCached(Vector<const char> name, Handle<String> source, SourceCodeCache* cache, v8::Extension* extension, bool use_runtime_context); Handle<Context> result_;};Genesis* Genesis::current_ = NULL;void Bootstrapper::Iterate(ObjectVisitor* v) { natives_cache.Iterate(v); extensions_cache.Iterate(v); PendingFixups::Iterate(v);}// While setting up the environment, we collect code positions that// need to be patched before we can run any code in the environment.void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) { PendingFixups::Add(code, masm);}bool Bootstrapper::IsActive() { return Genesis::current() != NULL;}Handle<Context> Bootstrapper::CreateEnvironment( Handle<Object> global_object, v8::Handle<v8::ObjectTemplate> global_template, v8::ExtensionConfiguration* extensions) { Genesis genesis(global_object, global_template, extensions); return genesis.result();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -