aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/factory.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/factory.cc')
-rw-r--r--deps/v8/src/factory.cc269
1 files changed, 208 insertions, 61 deletions
diff --git a/deps/v8/src/factory.cc b/deps/v8/src/factory.cc
index 1cdce60874..0e66ec6268 100644
--- a/deps/v8/src/factory.cc
+++ b/deps/v8/src/factory.cc
@@ -6,8 +6,8 @@
#include "src/allocation-site-scopes.h"
#include "src/base/bits.h"
+#include "src/bootstrapper.h"
#include "src/conversions.h"
-#include "src/isolate-inl.h"
#include "src/macro-assembler.h"
namespace v8 {
@@ -51,11 +51,21 @@ Handle<Box> Factory::NewBox(Handle<Object> value) {
}
+Handle<PrototypeInfo> Factory::NewPrototypeInfo() {
+ Handle<PrototypeInfo> result =
+ Handle<PrototypeInfo>::cast(NewStruct(PROTOTYPE_INFO_TYPE));
+ result->set_prototype_users(WeakFixedArray::Empty());
+ result->set_validity_cell(Smi::FromInt(0));
+ result->set_constructor_name(Smi::FromInt(0));
+ return result;
+}
+
+
Handle<Oddball> Factory::NewOddball(Handle<Map> map,
const char* to_string,
Handle<Object> to_number,
byte kind) {
- Handle<Oddball> oddball = New<Oddball>(map, OLD_POINTER_SPACE);
+ Handle<Oddball> oddball = New<Oddball>(map, OLD_SPACE);
Oddball::Initialize(isolate(), oddball, to_string, to_number, kind);
return oddball;
}
@@ -933,6 +943,8 @@ Handle<PropertyCell> Factory::NewPropertyCell() {
Handle<WeakCell> Factory::NewWeakCell(Handle<HeapObject> value) {
+ // It is safe to dereference the value because we are embedding it
+ // in cell and not inspecting its fields.
AllowDeferredHandleDereference convert_to_cell;
CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateWeakCell(*value),
WeakCell);
@@ -941,7 +953,7 @@ Handle<WeakCell> Factory::NewWeakCell(Handle<HeapObject> value) {
Handle<AllocationSite> Factory::NewAllocationSite() {
Handle<Map> map = allocation_site_map();
- Handle<AllocationSite> site = New<AllocationSite>(map, OLD_POINTER_SPACE);
+ Handle<AllocationSite> site = New<AllocationSite>(map, OLD_SPACE);
site->Initialize();
// Link the site
@@ -1098,12 +1110,6 @@ Handle<Object> Factory::NewSyntaxError(Handle<String> message) {
Handle<Object> Factory::NewReferenceError(const char* message,
- Vector<Handle<Object> > args) {
- return NewError("MakeReferenceError", message, args);
-}
-
-
-Handle<Object> Factory::NewReferenceError(const char* message,
Handle<JSArray> args) {
return NewError("MakeReferenceError", message, args);
}
@@ -1128,15 +1134,71 @@ Handle<Object> Factory::NewError(const char* maker, const char* message,
}
-Handle<Object> Factory::NewEvalError(const char* message,
- Vector<Handle<Object> > args) {
- return NewError("MakeEvalError", message, args);
+Handle<Object> Factory::NewError(const char* maker,
+ MessageTemplate::Template template_index,
+ Handle<Object> arg0, Handle<Object> arg1,
+ Handle<Object> arg2) {
+ HandleScope scope(isolate());
+ Handle<String> error_maker = InternalizeUtf8String(maker);
+ Handle<Object> fun_obj = Object::GetProperty(isolate()->js_builtins_object(),
+ error_maker).ToHandleChecked();
+
+ Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
+ Handle<Object> message_type(Smi::FromInt(template_index), isolate());
+ if (arg0.is_null()) arg0 = undefined_value();
+ if (arg1.is_null()) arg1 = undefined_value();
+ if (arg2.is_null()) arg2 = undefined_value();
+ Handle<Object> argv[] = {message_type, arg0, arg1, arg2};
+
+ // Invoke the JavaScript factory method. If an exception is thrown while
+ // running the factory method, use the exception as the result.
+ Handle<Object> result;
+ MaybeHandle<Object> exception;
+ if (!Execution::TryCall(fun, isolate()->js_builtins_object(), arraysize(argv),
+ argv, &exception).ToHandle(&result)) {
+ Handle<Object> exception_obj;
+ if (exception.ToHandle(&exception_obj)) {
+ result = exception_obj;
+ } else {
+ result = undefined_value();
+ }
+ }
+ return scope.CloseAndEscape(result);
}
-Handle<Object> Factory::NewError(const char* message,
- Vector<Handle<Object> > args) {
- return NewError("MakeError", message, args);
+Handle<Object> Factory::NewError(MessageTemplate::Template template_index,
+ Handle<Object> arg0, Handle<Object> arg1,
+ Handle<Object> arg2) {
+ return NewError("MakeError", template_index, arg0, arg1, arg2);
+}
+
+
+Handle<Object> Factory::NewTypeError(MessageTemplate::Template template_index,
+ Handle<Object> arg0, Handle<Object> arg1,
+ Handle<Object> arg2) {
+ return NewError("MakeTypeError", template_index, arg0, arg1, arg2);
+}
+
+
+Handle<Object> Factory::NewReferenceError(
+ MessageTemplate::Template template_index, Handle<Object> arg0,
+ Handle<Object> arg1, Handle<Object> arg2) {
+ return NewError("MakeReferenceError", template_index, arg0, arg1, arg2);
+}
+
+
+Handle<Object> Factory::NewRangeError(MessageTemplate::Template template_index,
+ Handle<Object> arg0, Handle<Object> arg1,
+ Handle<Object> arg2) {
+ return NewError("MakeRangeError", template_index, arg0, arg1, arg2);
+}
+
+
+Handle<Object> Factory::NewEvalError(MessageTemplate::Template template_index,
+ Handle<Object> arg0, Handle<Object> arg1,
+ Handle<Object> arg2) {
+ return NewError("MakeEvalError", template_index, arg0, arg1, arg2);
}
@@ -1254,7 +1316,7 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
Handle<SharedFunctionInfo> info,
Handle<Context> context,
PretenureFlag pretenure) {
- AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE;
+ AllocationSpace space = pretenure == TENURED ? OLD_SPACE : NEW_SPACE;
Handle<JSFunction> result = New<JSFunction>(map, space);
InitializeFunction(result, info, context);
return result;
@@ -1271,7 +1333,8 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
map.is_identical_to(
isolate()->sloppy_function_without_prototype_map()) ||
map.is_identical_to(
- isolate()->sloppy_function_with_readonly_prototype_map())));
+ isolate()->sloppy_function_with_readonly_prototype_map()) ||
+ map.is_identical_to(isolate()->strict_function_map())));
return NewFunction(map, info, context);
}
@@ -1283,19 +1346,27 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name) {
Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
- Handle<Code> code) {
- return NewFunction(
- isolate()->sloppy_function_without_prototype_map(), name, code);
+ Handle<Code> code,
+ bool is_strict) {
+ Handle<Map> map = is_strict
+ ? isolate()->strict_function_without_prototype_map()
+ : isolate()->sloppy_function_without_prototype_map();
+ return NewFunction(map, name, code);
}
-Handle<JSFunction> Factory::NewFunction(Handle<String> name,
- Handle<Code> code,
+Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype,
- bool read_only_prototype) {
- Handle<Map> map = read_only_prototype
- ? isolate()->sloppy_function_with_readonly_prototype_map()
- : isolate()->sloppy_function_map();
+ bool read_only_prototype,
+ bool is_strict) {
+ // In strict mode, readonly strict map is only available during bootstrap
+ DCHECK(!is_strict || !read_only_prototype ||
+ isolate()->bootstrapper()->IsActive());
+ Handle<Map> map =
+ is_strict ? isolate()->strict_function_map()
+ : read_only_prototype
+ ? isolate()->sloppy_function_with_readonly_prototype_map()
+ : isolate()->sloppy_function_map();
Handle<JSFunction> result = NewFunction(map, name, code);
result->set_prototype_or_initial_map(*prototype);
return result;
@@ -1306,10 +1377,11 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype,
InstanceType type, int instance_size,
bool read_only_prototype,
- bool install_constructor) {
+ bool install_constructor,
+ bool is_strict) {
// Allocate the function
- Handle<JSFunction> function = NewFunction(
- name, code, prototype, read_only_prototype);
+ Handle<JSFunction> function =
+ NewFunction(name, code, prototype, read_only_prototype, is_strict);
ElementsKind elements_kind =
type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS;
@@ -1366,11 +1438,6 @@ Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
}
-static bool ShouldOptimizeNewClosure(Handle<SharedFunctionInfo> info) {
- return !info->is_toplevel() && info->allows_lazy_compilation();
-}
-
-
Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
Handle<SharedFunctionInfo> info,
Handle<Context> context,
@@ -1384,6 +1451,10 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
info->ResetForNewContext(isolate()->heap()->global_ic_age());
}
+ if (FLAG_always_opt && info->allows_lazy_compilation()) {
+ result->MarkForOptimization();
+ }
+
int index = info->SearchOptimizedCodeMap(context->native_context(),
BailoutId::None());
if (!info->bound() && index < 0) {
@@ -1399,12 +1470,8 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
Code* code = info->GetCodeFromOptimizedCodeMap(index);
DCHECK(!code->marked_for_deoptimization());
result->ReplaceCode(code);
- return result;
}
- if (FLAG_always_opt && ShouldOptimizeNewClosure(info)) {
- result->MarkForOptimization();
- }
return result;
}
@@ -1587,7 +1654,7 @@ Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) {
}
// Allocate the global object and initialize it with the backing store.
- Handle<GlobalObject> global = New<GlobalObject>(map, OLD_POINTER_SPACE);
+ Handle<GlobalObject> global = New<GlobalObject>(map, OLD_SPACE);
isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map);
// Create a new map for the global object.
@@ -1763,9 +1830,38 @@ size_t GetExternalArrayElementSize(ExternalArrayType type) {
case kExternal##Type##Array: \
return size;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+#undef TYPED_ARRAY_CASE
+}
+
+
+size_t GetFixedTypedArraysElementSize(ElementsKind kind) {
+ switch (kind) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: \
+ return size;
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+#undef TYPED_ARRAY_CASE
+}
+
+
+ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) {
+ switch (kind) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: \
+ return kExternal##Type##Array;
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ default:
+ UNREACHABLE();
+ return kExternalInt8Array;
}
- UNREACHABLE();
- return 0;
#undef TYPED_ARRAY_CASE
}
@@ -1787,6 +1883,23 @@ JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) {
}
+JSFunction* GetTypedArrayFun(ElementsKind elements_kind, Isolate* isolate) {
+ Context* native_context = isolate->context()->native_context();
+ switch (elements_kind) {
+#define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: \
+ return native_context->type##_array_fun();
+
+ TYPED_ARRAYS(TYPED_ARRAY_FUN)
+#undef TYPED_ARRAY_FUN
+
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
void SetupArrayBufferView(i::Isolate* isolate,
i::Handle<i::JSArrayBufferView> obj,
i::Handle<i::JSArrayBuffer> buffer,
@@ -1796,15 +1909,6 @@ void SetupArrayBufferView(i::Isolate* isolate,
obj->set_buffer(*buffer);
- Heap* heap = isolate->heap();
- if (heap->InNewSpace(*obj)) {
- obj->set_weak_next(heap->new_array_buffer_views_list());
- heap->set_new_array_buffer_views_list(*obj);
- } else {
- obj->set_weak_next(buffer->weak_first_view());
- buffer->set_weak_first_view(*obj);
- }
-
i::Handle<i::Object> byte_offset_object =
isolate->factory()->NewNumberFromSize(byte_offset);
obj->set_byte_offset(*byte_offset_object);
@@ -1828,6 +1932,16 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) {
}
+Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind) {
+ Handle<JSFunction> typed_array_fun_handle(
+ GetTypedArrayFun(elements_kind, isolate()));
+
+ CALL_HEAP_FUNCTION(
+ isolate(), isolate()->heap()->AllocateJSObject(*typed_array_fun_handle),
+ JSTypedArray);
+}
+
+
Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
Handle<JSArrayBuffer> buffer,
size_t byte_offset,
@@ -1856,6 +1970,36 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
}
+Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind,
+ size_t number_of_elements) {
+ Handle<JSTypedArray> obj = NewJSTypedArray(elements_kind);
+
+ size_t element_size = GetFixedTypedArraysElementSize(elements_kind);
+ ExternalArrayType array_type = GetArrayTypeFromElementsKind(elements_kind);
+
+ CHECK(number_of_elements <=
+ (std::numeric_limits<size_t>::max() / element_size));
+ CHECK(number_of_elements <= static_cast<size_t>(Smi::kMaxValue));
+ size_t byte_length = number_of_elements * element_size;
+
+ obj->set_byte_offset(Smi::FromInt(0));
+ i::Handle<i::Object> byte_length_object =
+ isolate()->factory()->NewNumberFromSize(byte_length);
+ obj->set_byte_length(*byte_length_object);
+ Handle<Object> length_object = NewNumberFromSize(number_of_elements);
+ obj->set_length(*length_object);
+
+ Handle<JSArrayBuffer> buffer = isolate()->factory()->NewJSArrayBuffer();
+ Runtime::SetupArrayBuffer(isolate(), buffer, true, NULL, byte_length);
+ obj->set_buffer(*buffer);
+ Handle<FixedTypedArrayBase> elements =
+ isolate()->factory()->NewFixedTypedArray(
+ static_cast<int>(number_of_elements), array_type);
+ obj->set_elements(*elements);
+ return obj;
+}
+
+
Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
size_t byte_offset,
size_t byte_length) {
@@ -1871,7 +2015,7 @@ Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler,
// TODO(rossberg): Once we optimize proxies, think about a scheme to share
// maps. Will probably depend on the identity of the handler object, too.
Handle<Map> map = NewMap(JS_PROXY_TYPE, JSProxy::kSize);
- map->SetPrototype(prototype);
+ Map::SetPrototype(map, prototype);
// Allocate the proxy object.
Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE);
@@ -1890,7 +2034,7 @@ Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler,
// TODO(rossberg): Once we optimize proxies, think about a scheme to share
// maps. Will probably depend on the identity of the handler object, too.
Handle<Map> map = NewMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
- map->SetPrototype(prototype);
+ Map::SetPrototype(map, prototype);
// Allocate the proxy object.
Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE);
@@ -1915,7 +2059,8 @@ void Factory::ReinitializeJSProxy(Handle<JSProxy> proxy, InstanceType type,
int size_difference = proxy->map()->instance_size() - map->instance_size();
DCHECK(size_difference >= 0);
- map->SetPrototype(handle(proxy->map()->prototype(), proxy->GetIsolate()));
+ Handle<Object> prototype(proxy->map()->prototype(), isolate());
+ Map::SetPrototype(map, prototype);
// Allocate the backing storage for the properties.
int prop_size = map->InitialPropertiesLength();
@@ -1938,7 +2083,8 @@ void Factory::ReinitializeJSProxy(Handle<JSProxy> proxy, InstanceType type,
if (size_difference > 0) {
Address address = proxy->address();
heap->CreateFillerObjectAt(address + map->instance_size(), size_difference);
- heap->AdjustLiveBytes(address, -size_difference, Heap::FROM_MUTATOR);
+ heap->AdjustLiveBytes(address, -size_difference,
+ Heap::CONCURRENT_TO_SWEEPER);
}
// Reset the map for the object.
@@ -2075,8 +2221,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
Handle<String> name,
MaybeHandle<Code> maybe_code) {
Handle<Map> map = shared_function_info_map();
- Handle<SharedFunctionInfo> share =
- New<SharedFunctionInfo>(map, OLD_POINTER_SPACE);
+ Handle<SharedFunctionInfo> share = New<SharedFunctionInfo>(map, OLD_SPACE);
// Set pointer fields.
share->set_name(*name);
@@ -2256,7 +2401,9 @@ Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
bool* is_result_from_cache) {
const int kMapCacheSize = 128;
- if (number_of_properties > kMapCacheSize) {
+ // We do not cache maps for too many properties or when running builtin code.
+ if (number_of_properties > kMapCacheSize ||
+ isolate()->bootstrapper()->IsActive()) {
*is_result_from_cache = false;
return Map::Create(isolate(), number_of_properties);
}
@@ -2327,10 +2474,10 @@ void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp,
}
-Handle<Object> Factory::GlobalConstantFor(Handle<String> name) {
- if (String::Equals(name, undefined_string())) return undefined_value();
- if (String::Equals(name, nan_string())) return nan_value();
- if (String::Equals(name, infinity_string())) return infinity_value();
+Handle<Object> Factory::GlobalConstantFor(Handle<Name> name) {
+ if (Name::Equals(name, undefined_string())) return undefined_value();
+ if (Name::Equals(name, nan_string())) return nan_value();
+ if (Name::Equals(name, infinity_string())) return infinity_value();
return Handle<Object>::null();
}