13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_API_H_
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_API_H_
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h"
985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8-testing.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/contexts.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/factory.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/list-inl.h"
15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Constants used in the implementation of the API.  The most natural thing
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// would usually be to place these with the classes that use them, but
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// we want to keep them out of v8.h because it is an externally
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// visible file.
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Consts {
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum TemplateType {
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    FUNCTION_TEMPLATE = 0,
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    OBJECT_TEMPLATE = 1
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utilities for working with neander-objects, primitive
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// env-independent JSObjects used by the api.
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass NeanderObject {
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit NeanderObject(v8::internal::Isolate* isolate, int size);
368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  explicit inline NeanderObject(v8::internal::Handle<v8::internal::Object> obj);
378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  explicit inline NeanderObject(v8::internal::Object* obj);
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline v8::internal::Object* get(int index);
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void set(int index, v8::internal::Object* value);
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline v8::internal::Handle<v8::internal::JSObject> value() { return value_; }
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int size();
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::internal::Handle<v8::internal::JSObject> value_;
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utilities for working with neander-arrays, a simple extensible
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// array abstraction built on neander-objects.
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass NeanderArray {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit NeanderArray(v8::internal::Isolate* isolate);
528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  explicit inline NeanderArray(v8::internal::Handle<v8::internal::Object> obj);
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline v8::internal::Handle<v8::internal::JSObject> value() {
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return obj_.value();
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void add(v8::internal::Handle<v8::internal::Object> value);
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int length();
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::internal::Object* get(int index);
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Change the value at an index to undefined value. If the index is
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // out of bounds, the request is ignored. Returns the old value.
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set(int index, v8::internal::Object* value);
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  NeanderObject obj_;
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockNeanderObject::NeanderObject(v8::internal::Handle<v8::internal::Object> obj)
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : value_(v8::internal::Handle<v8::internal::JSObject>::cast(obj)) { }
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockNeanderObject::NeanderObject(v8::internal::Object* obj)
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : value_(v8::internal::Handle<v8::internal::JSObject>(
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        v8::internal::JSObject::cast(obj))) { }
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockNeanderArray::NeanderArray(v8::internal::Handle<v8::internal::Object> obj)
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : obj_(obj) { }
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::internal::Object* NeanderObject::get(int offset) {
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(value()->HasFastObjectElements());
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return v8::internal::FixedArray::cast(value()->elements())->get(offset);
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid NeanderObject::set(int offset, v8::internal::Object* value) {
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(value_->HasFastObjectElements());
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::internal::FixedArray::cast(value_->elements())->set(offset, value);
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename T> inline T ToCData(v8::internal::Object* obj) {
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<T>(
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      reinterpret_cast<intptr_t>(
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          v8::internal::Foreign::cast(obj)->foreign_address()));
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <typename T>
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline v8::internal::Handle<v8::internal::Object> FromCData(
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::internal::Isolate* isolate, T obj) {
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->factory()->NewForeign(
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj)));
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
112d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockclass ApiFunction {
113d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block public:
114d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { }
115d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::internal::Address address() { return addr_; }
116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block private:
117d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::internal::Address addr_;
118d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block};
119d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RegisteredExtension {
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit RegisteredExtension(Extension* extension);
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void Register(RegisteredExtension* that);
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void UnregisterAll();
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Extension* extension() { return extension_; }
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegisteredExtension* next() { return next_; }
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static RegisteredExtension* first_extension() { return first_extension_; }
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Extension* extension_;
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegisteredExtension* next_;
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static RegisteredExtension* first_extension_;
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define OPEN_HANDLE_LIST(V)                    \
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Template, TemplateInfo)                    \
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(FunctionTemplate, FunctionTemplateInfo)    \
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ObjectTemplate, ObjectTemplateInfo)        \
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Signature, SignatureInfo)                  \
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(AccessorSignature, FunctionTemplateInfo)   \
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(TypeSwitch, TypeSwitchInfo)                \
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Data, Object)                              \
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(RegExp, JSRegExp)                          \
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Object, JSObject)                          \
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Array, JSArray)                            \
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ArrayBuffer, JSArrayBuffer)                \
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ArrayBufferView, JSArrayBufferView)        \
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(TypedArray, JSTypedArray)                  \
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Uint8Array, JSTypedArray)                  \
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Uint8ClampedArray, JSTypedArray)           \
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Int8Array, JSTypedArray)                   \
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Uint16Array, JSTypedArray)                 \
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Int16Array, JSTypedArray)                  \
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Uint32Array, JSTypedArray)                 \
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Int32Array, JSTypedArray)                  \
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Float32Array, JSTypedArray)                \
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Float64Array, JSTypedArray)                \
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(DataView, JSDataView)                      \
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Name, Name)                                \
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(String, String)                            \
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Symbol, Symbol)                            \
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Script, JSFunction)                        \
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(UnboundScript, SharedFunctionInfo)         \
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Function, JSFunction)                      \
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Message, JSMessageObject)                  \
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Context, Context)                          \
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(External, Object)                          \
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StackTrace, JSArray)                       \
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(StackFrame, JSObject)                      \
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(DeclaredAccessorDescriptor, DeclaredAccessorDescriptor)
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Utils {
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool ApiCheck(bool condition,
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              const char* location,
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              const char* message) {
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!condition) Utils::ReportApiFailure(location, message);
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return condition;
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Local<FunctionTemplate> ToFunctionTemplate(NeanderObject obj);
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Local<ObjectTemplate> ToObjectTemplate(NeanderObject obj);
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Context> ToLocal(
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::Context> obj);
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Value> ToLocal(
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::Object> obj);
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Function> ToLocal(
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::JSFunction> obj);
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Name> ToLocal(
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::Name> obj);
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<String> ToLocal(
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::String> obj);
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Symbol> ToLocal(
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::Symbol> obj);
199f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  static inline Local<RegExp> ToLocal(
200f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch      v8::internal::Handle<v8::internal::JSRegExp> obj);
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Object> ToLocal(
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::JSObject> obj);
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Array> ToLocal(
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::JSArray> obj);
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<ArrayBuffer> ToLocal(
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSArrayBuffer> obj);
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<ArrayBufferView> ToLocal(
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSArrayBufferView> obj);
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<DataView> ToLocal(
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSDataView> obj);
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<TypedArray> ToLocal(
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Uint8Array> ToLocalUint8Array(
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Uint8ClampedArray> ToLocalUint8ClampedArray(
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Int8Array> ToLocalInt8Array(
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Uint16Array> ToLocalUint16Array(
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Int16Array> ToLocalInt16Array(
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Uint32Array> ToLocalUint32Array(
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Int32Array> ToLocalInt32Array(
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Float32Array> ToLocalFloat32Array(
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<Float64Array> ToLocalFloat64Array(
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj);
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Message> MessageToLocal(
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::Object> obj);
23525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  static inline Local<StackTrace> StackTraceToLocal(
23625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      v8::internal::Handle<v8::internal::JSArray> obj);
23725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  static inline Local<StackFrame> StackFrameToLocal(
23825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      v8::internal::Handle<v8::internal::JSObject> obj);
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Number> NumberToLocal(
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::Object> obj);
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Integer> IntegerToLocal(
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::Object> obj);
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Uint32> Uint32ToLocal(
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::Object> obj);
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<FunctionTemplate> ToLocal(
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<ObjectTemplate> ToLocal(
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::ObjectTemplateInfo> obj);
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<Signature> ToLocal(
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::SignatureInfo> obj);
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<AccessorSignature> AccessorSignatureToLocal(
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj);
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline Local<TypeSwitch> ToLocal(
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::internal::Handle<v8::internal::TypeSwitchInfo> obj);
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<External> ExternalToLocal(
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSObject> obj);
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<DeclaredAccessorDescriptor> ToLocal(
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::DeclaredAccessorDescriptor> obj);
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_OPEN_HANDLE(From, To) \
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline v8::internal::Handle<v8::internal::To> \
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      OpenHandle(const From* that, bool allow_empty_handle = false);
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOPEN_HANDLE_LIST(DECLARE_OPEN_HANDLE)
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_OPEN_HANDLE
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class From, class To>
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Local<To> Convert(v8::internal::Handle<From> obj) {
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(obj.is_null() || !obj->IsTheHole());
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Local<To>(reinterpret_cast<To*>(obj.location()));
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <class T>
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const v8::Persistent<T>& persistent) {
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return v8::internal::Handle<v8::internal::Object>(
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<v8::internal::Object**>(persistent.val_));
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <class T>
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline v8::internal::Handle<v8::internal::Object> OpenPersistent(
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::Persistent<T>* persistent) {
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return OpenPersistent(*persistent);
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <class From, class To>
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline v8::internal::Handle<To> OpenHandle(v8::Local<From> handle) {
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return OpenHandle(*handle);
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void ReportApiFailure(const char* location, const char* message);
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <class T>
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom(
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::EscapableHandleScope* scope) {
3006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  v8::internal::Handle<T> handle;
3016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!is_null()) {
3026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    handle = *this;
3036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(*scope->Escape(Utils::ToLocal(handle)), true);
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <class T>
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) {
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<T*>(obj.location());
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <class T>
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline v8::Local<T> ToApiHandle(
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::internal::Handle<v8::internal::Object> obj) {
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::Convert<v8::internal::Object, T>(obj);
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementations of ToLocal
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_TO_LOCAL(Name, From, To)                                       \
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Convert<v8::internal::From, v8::To>(obj);  \
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define MAKE_TO_LOCAL_TYPED_ARRAY(Type, typeName, TYPE, ctype, size)        \
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Local<v8::Type##Array> Utils::ToLocal##Type##Array(                       \
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::JSTypedArray> obj) {               \
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(obj->type() == kExternal##Type##Array);                          \
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Convert<v8::internal::JSTypedArray, v8::Type##Array>(obj);       \
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, Context, Context)
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, Object, Value)
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, JSFunction, Function)
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAKE_TO_LOCAL(ToLocal, Name, Name)
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, String, String)
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAKE_TO_LOCAL(ToLocal, Symbol, Symbol)
342f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochMAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp)
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, JSObject, Object)
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, JSArray, Array)
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAKE_TO_LOCAL(ToLocal, JSArrayBuffer, ArrayBuffer)
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAKE_TO_LOCAL(ToLocal, JSArrayBufferView, ArrayBufferView)
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAKE_TO_LOCAL(ToLocal, JSDataView, DataView)
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAKE_TO_LOCAL(ToLocal, JSTypedArray, TypedArray)
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTYPED_ARRAYS(MAKE_TO_LOCAL_TYPED_ARRAY)
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate)
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate)
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, SignatureInfo, Signature)
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature)
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, TypeSwitchInfo, TypeSwitch)
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(MessageToLocal, Object, Message)
35825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenMAKE_TO_LOCAL(StackTraceToLocal, JSArray, StackTrace)
35925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenMAKE_TO_LOCAL(StackFrameToLocal, JSObject, StackFrame)
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(NumberToLocal, Object, Number)
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(IntegerToLocal, Object, Integer)
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAKE_TO_LOCAL(ExternalToLocal, JSObject, External)
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMAKE_TO_LOCAL(ToLocal, DeclaredAccessorDescriptor, DeclaredAccessorDescriptor)
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef MAKE_TO_LOCAL_TYPED_ARRAY
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_TO_LOCAL
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementations of OpenHandle
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define MAKE_OPEN_HANDLE(From, To)                                          \
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::internal::Handle<v8::internal::To> Utils::OpenHandle(                 \
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const v8::From* that, bool allow_empty_handle) {                        \
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXTRA_CHECK(allow_empty_handle || that != NULL);                        \
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXTRA_CHECK(that == NULL ||                                             \
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (*reinterpret_cast<v8::internal::Object* const*>(that))->Is##To()); \
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return v8::internal::Handle<v8::internal::To>(                          \
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        reinterpret_cast<v8::internal::To**>(const_cast<v8::From*>(that))); \
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOPEN_HANDLE_LIST(MAKE_OPEN_HANDLE)
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_OPEN_HANDLE
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef OPEN_HANDLE_LIST
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Tracks string usage to help make better decisions when
39144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// externalizing strings.
39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block//
39344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Implementation note: internally this class only tracks fresh
39444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// strings and keeps a single use counter for them.
39544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StringTracker {
39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
39744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Records that the given string's characters were copied to some
39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // external buffer. If this happens often we should honor
39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // externalization requests for the string.
40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void RecordWrite(Handle<String> string) {
40144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Address address = reinterpret_cast<Address>(*string);
40244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Address top = isolate_->heap()->NewSpaceTop();
40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (IsFreshString(address, top)) {
40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      IncrementUseCount(top);
40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
40644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
40744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Estimates freshness and use frequency of the given string based
40944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // on how close it is to the new space top and the recorded usage
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // history.
41144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline bool IsFreshUnusedString(Handle<String> string) {
41244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Address address = reinterpret_cast<Address>(*string);
41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Address top = isolate_->heap()->NewSpaceTop();
41444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return IsFreshString(address, top) && IsUseCountLow(top);
41544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
41644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
41744f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
41844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StringTracker() : use_count_(0), last_top_(NULL), isolate_(NULL) { }
41944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
42044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static inline bool IsFreshString(Address string, Address top) {
42144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return top - kFreshnessLimit <= string && string <= top;
42244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
42344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
42444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline bool IsUseCountLow(Address top) {
42544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (last_top_ != top) return true;
42644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return use_count_ < kUseLimit;
42744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
42844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
42944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  inline void IncrementUseCount(Address top) {
43044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (last_top_ != top) {
43144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      use_count_ = 0;
43244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      last_top_ = top;
43344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
43444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ++use_count_;
43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
43644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
43744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Single use counter shared by all fresh strings.
43844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int use_count_;
43944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
44044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Last new space top when the use count above was valid.
44144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address last_top_;
44244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
44344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate_;
44444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
44544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // How close to the new space top a fresh string has to be.
44644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const int kFreshnessLimit = 1024;
44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
44844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The number of uses required to consider a string useful.
44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const int kUseLimit = 32;
45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
45144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class Isolate;
45244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
45344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DISALLOW_COPY_AND_ASSIGN(StringTracker);
45444f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
45644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DeferredHandles {
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~DeferredHandles();
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeferredHandles(Object** first_block_limit, Isolate* isolate)
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : next_(NULL),
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        previous_(NULL),
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        first_block_limit_(first_block_limit),
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate_(isolate) {
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->LinkDeferredHandles(this);
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Iterate(ObjectVisitor* v);
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  List<Object**> blocks_;
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeferredHandles* next_;
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeferredHandles* previous_;
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** first_block_limit_;
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate_;
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class HandleScopeImplementer;
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class Isolate;
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This class is here in order to be able to declare it a friend of
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HandleScope.  Moving these methods to be members of HandleScope would be
48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// neat in some ways, but it would expose internal implementation details in
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// our public header file, which is undesirable.
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
48844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// An isolate has a single instance of this class to hold the current thread's
48944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// data. In multithreaded V8 programs this data is copied in and out of storage
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// so that the currently executing thread always has its own copy of this
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// data.
492257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass HandleScopeImplementer {
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
494257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  explicit HandleScopeImplementer(Isolate* isolate)
495257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      : isolate_(isolate),
496257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        blocks_(0),
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        entered_contexts_(0),
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        saved_contexts_(0),
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        spare_(NULL),
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        call_depth_(0),
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        last_handle_before_deferred_block_(NULL) { }
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
50369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  ~HandleScopeImplementer() {
50469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    DeleteArray(spare_);
50569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
50669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Threading support for handle data.
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int ArchiveSpacePerThread();
50944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  char* RestoreThread(char* from);
51044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  char* ArchiveThread(char* to);
51144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void FreeThreadResources();
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Garbage collection support.
51444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Iterate(v8::internal::ObjectVisitor* v);
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static char* Iterate(v8::internal::ObjectVisitor* v, char* data);
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline internal::Object** GetSpareOrNewBlock();
5195913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  inline void DeleteExtensions(internal::Object** prev_limit);
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void IncrementCallDepth() {call_depth_++;}
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void DecrementCallDepth() {call_depth_--;}
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool CallDepthIsZero() { return call_depth_ == 0; }
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void EnterContext(Handle<Context> context);
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void LeaveContext();
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool LastEnteredContextWas(Handle<Context> context);
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Returns the last entered context or an empty handle if no
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // contexts have been entered.
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline Handle<Context> LastEnteredContext();
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void SaveContext(Context* context);
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Context* RestoreContext();
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool HasSavedContexts();
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline List<internal::Object**>* blocks() { return &blocks_; }
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return isolate_; }
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ReturnBlock(Object** block) {
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(block != NULL);
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (spare_ != NULL) DeleteArray(spare_);
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    spare_ = block;
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void ResetAfterArchive() {
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    blocks_.Initialize(0);
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    entered_contexts_.Initialize(0);
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    saved_contexts_.Initialize(0);
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    spare_ = NULL;
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    last_handle_before_deferred_block_ = NULL;
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    call_depth_ = 0;
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Free() {
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(blocks_.length() == 0);
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(entered_contexts_.length() == 0);
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(saved_contexts_.length() == 0);
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    blocks_.Free();
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    entered_contexts_.Free();
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    saved_contexts_.Free();
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (spare_ != NULL) {
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      DeleteArray(spare_);
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      spare_ = NULL;
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(call_depth_ == 0);
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BeginDeferredScope();
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeferredHandles* Detach(Object** prev_limit);
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Isolate* isolate_;
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  List<internal::Object**> blocks_;
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Used as a stack to keep track of entered contexts.
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  List<Context*> entered_contexts_;
577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Used as a stack to keep track of saved contexts.
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  List<Context*> saved_contexts_;
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object** spare_;
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int call_depth_;
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object** last_handle_before_deferred_block_;
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This is only used for threading support.
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScopeData handle_scope_data_;
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IterateThis(ObjectVisitor* v);
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* RestoreThreadHelper(char* from);
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  char* ArchiveThreadHelper(char* to);
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class DeferredHandles;
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class DeferredHandleScope;
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer);
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kHandleBlockSize = v8::internal::KB - 2;  // fit in one page
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HandleScopeImplementer::SaveContext(Context* context) {
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  saved_contexts_.Add(context);
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockContext* HandleScopeImplementer::RestoreContext() {
605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return saved_contexts_.RemoveLast();
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool HandleScopeImplementer::HasSavedContexts() {
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return !saved_contexts_.is_empty();
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HandleScopeImplementer::EnterContext(Handle<Context> context) {
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  entered_contexts_.Add(*context);
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HandleScopeImplementer::LeaveContext() {
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  entered_contexts_.RemoveLast();
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool HandleScopeImplementer::LastEnteredContextWas(Handle<Context> context) {
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return !entered_contexts_.is_empty() && entered_contexts_.last() == *context;
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Context> HandleScopeImplementer::LastEnteredContext() {
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (entered_contexts_.is_empty()) return Handle<Context>::null();
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Context>(entered_contexts_.last());
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If there's a spare block, use it for growing the current scope.
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinternal::Object** HandleScopeImplementer::GetSpareOrNewBlock() {
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  internal::Object** block = (spare_ != NULL) ?
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      spare_ :
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      NewArray<internal::Object*>(kHandleBlockSize);
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  spare_ = NULL;
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return block;
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6455913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckvoid HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) {
6465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  while (!blocks_.is_empty()) {
6475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    internal::Object** block_start = blocks_.last();
6485913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    internal::Object** block_limit = block_start + kHandleBlockSize;
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // SealHandleScope may make the prev_limit to point inside the block.
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (block_start <= prev_limit && prev_limit <= block_limit) {
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef ENABLE_HANDLE_ZAPPING
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      internal::HandleScope::ZapRange(prev_limit, block_limit);
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
6575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck#else
6585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (prev_limit == block_limit) break;
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
6605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
6615913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    blocks_.RemoveLast();
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef ENABLE_HANDLE_ZAPPING
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    internal::HandleScope::ZapRange(block_start, block_limit);
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
6655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (spare_ != NULL) {
6665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      DeleteArray(spare_);
6675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
6685913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    spare_ = block_start;
6695913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((blocks_.is_empty() && prev_limit == NULL) ||
6715913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck         (!blocks_.is_empty() && prev_limit != NULL));
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Interceptor functions called from generated inline caches to notify
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CPU profiler that external callbacks are invoked.
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InvokeAccessorGetterCallback(
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Local<v8::Name> property,
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const v8::PropertyCallbackInfo<v8::Value>& info,
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::AccessorNameGetterCallback getter);
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            v8::FunctionCallback callback);
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass Testing {
686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static v8::Testing::StressType stress_type() { return stress_type_; }
688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static void set_stress_type(v8::Testing::StressType stress_type) {
689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    stress_type_ = stress_type;
690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static v8::Testing::StressType stress_type_;
694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_API_H_
699