1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_BOOTSTRAPPER_H_
6#define V8_BOOTSTRAPPER_H_
7
8#include "src/factory.h"
9
10namespace v8 {
11namespace internal {
12
13// A SourceCodeCache uses a FixedArray to store pairs of
14// (OneByteString*, JSFunction*), mapping names of native code files
15// (runtime.js, etc.) to precompiled functions. Instead of mapping
16// names to functions it might make sense to let the JS2C tool
17// generate an index for each native JS file.
18class SourceCodeCache FINAL BASE_EMBEDDED {
19 public:
20  explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { }
21
22  void Initialize(Isolate* isolate, bool create_heap_objects) {
23    cache_ = create_heap_objects ? isolate->heap()->empty_fixed_array() : NULL;
24  }
25
26  void Iterate(ObjectVisitor* v) {
27    v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_));
28  }
29
30  bool Lookup(Vector<const char> name, Handle<SharedFunctionInfo>* handle) {
31    for (int i = 0; i < cache_->length(); i+=2) {
32      SeqOneByteString* str = SeqOneByteString::cast(cache_->get(i));
33      if (str->IsUtf8EqualTo(name)) {
34        *handle = Handle<SharedFunctionInfo>(
35            SharedFunctionInfo::cast(cache_->get(i + 1)));
36        return true;
37      }
38    }
39    return false;
40  }
41
42  void Add(Vector<const char> name, Handle<SharedFunctionInfo> shared) {
43    Isolate* isolate = shared->GetIsolate();
44    Factory* factory = isolate->factory();
45    HandleScope scope(isolate);
46    int length = cache_->length();
47    Handle<FixedArray> new_array = factory->NewFixedArray(length + 2, TENURED);
48    cache_->CopyTo(0, *new_array, 0, cache_->length());
49    cache_ = *new_array;
50    Handle<String> str =
51        factory->NewStringFromAscii(name, TENURED).ToHandleChecked();
52    DCHECK(!str.is_null());
53    cache_->set(length, *str);
54    cache_->set(length + 1, *shared);
55    Script::cast(shared->script())->set_type(Smi::FromInt(type_));
56  }
57
58 private:
59  Script::Type type_;
60  FixedArray* cache_;
61  DISALLOW_COPY_AND_ASSIGN(SourceCodeCache);
62};
63
64
65// The Boostrapper is the public interface for creating a JavaScript global
66// context.
67class Bootstrapper FINAL {
68 public:
69  static void InitializeOncePerProcess();
70  static void TearDownExtensions();
71
72  // Requires: Heap::SetUp has been called.
73  void Initialize(bool create_heap_objects);
74  void TearDown();
75
76  // Creates a JavaScript Global Context with initial object graph.
77  // The returned value is a global handle casted to V8Environment*.
78  Handle<Context> CreateEnvironment(
79      MaybeHandle<JSGlobalProxy> maybe_global_proxy,
80      v8::Handle<v8::ObjectTemplate> global_object_template,
81      v8::ExtensionConfiguration* extensions);
82
83  // Detach the environment from its outer global object.
84  void DetachGlobal(Handle<Context> env);
85
86  // Traverses the pointers for memory management.
87  void Iterate(ObjectVisitor* v);
88
89  // Accessor for the native scripts source code.
90  Handle<String> NativesSourceLookup(int index);
91
92  // Tells whether bootstrapping is active.
93  bool IsActive() const { return nesting_ != 0; }
94
95  // Support for thread preemption.
96  static int ArchiveSpacePerThread();
97  char* ArchiveState(char* to);
98  char* RestoreState(char* from);
99  void FreeThreadResources();
100
101  // This will allocate a char array that is deleted when V8 is shut down.
102  // It should only be used for strictly finite allocations.
103  char* AllocateAutoDeletedArray(int bytes);
104
105  // Used for new context creation.
106  bool InstallExtensions(Handle<Context> native_context,
107                         v8::ExtensionConfiguration* extensions);
108
109  SourceCodeCache* extensions_cache() { return &extensions_cache_; }
110
111 private:
112  Isolate* isolate_;
113  typedef int NestingCounterType;
114  NestingCounterType nesting_;
115  SourceCodeCache extensions_cache_;
116  // This is for delete, not delete[].
117  List<char*>* delete_these_non_arrays_on_tear_down_;
118  // This is for delete[]
119  List<char*>* delete_these_arrays_on_tear_down_;
120
121  friend class BootstrapperActive;
122  friend class Isolate;
123  friend class NativesExternalStringResource;
124
125  explicit Bootstrapper(Isolate* isolate);
126
127  static v8::Extension* free_buffer_extension_;
128  static v8::Extension* gc_extension_;
129  static v8::Extension* externalize_string_extension_;
130  static v8::Extension* statistics_extension_;
131  static v8::Extension* trigger_failure_extension_;
132
133  DISALLOW_COPY_AND_ASSIGN(Bootstrapper);
134};
135
136
137class BootstrapperActive FINAL BASE_EMBEDDED {
138 public:
139  explicit BootstrapperActive(Bootstrapper* bootstrapper)
140      : bootstrapper_(bootstrapper) {
141    ++bootstrapper_->nesting_;
142  }
143
144  ~BootstrapperActive() {
145    --bootstrapper_->nesting_;
146  }
147
148 private:
149  Bootstrapper* bootstrapper_;
150
151  DISALLOW_COPY_AND_ASSIGN(BootstrapperActive);
152};
153
154
155class NativesExternalStringResource FINAL
156    : public v8::String::ExternalOneByteStringResource {
157 public:
158  NativesExternalStringResource(Bootstrapper* bootstrapper,
159                                const char* source,
160                                size_t length);
161  virtual const char* data() const OVERRIDE { return data_; }
162  virtual size_t length() const OVERRIDE { return length_; }
163
164 private:
165  const char* data_;
166  size_t length_;
167};
168
169}}  // namespace v8::internal
170
171#endif  // V8_BOOTSTRAPPER_H_
172