Update V8 to r4588
We're using WebKit r58033, as used by
http://src.chromium.org/svn/releases/5.0.387.0/DEPS
This requires http://v8.googlecode.com/svn/trunk@4465 but this version has a
crashing bug for ARM. Instead we use http://v8.googlecode.com/svn/trunk@4588,
which is used by http://src.chromium.org/svn/releases/6.0.399.0/DEPS
Note that a trivial bug fix was required in arm/codegen-arm.cc. This is guarded
with ANDROID. See http://code.google.com/p/v8/issues/detail?id=703
Change-Id: I459647a8286c4f8c7405f0c5581ecbf051a6f1e8
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 225865c..657d0dc 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -55,15 +55,16 @@
}
void Iterate(ObjectVisitor* v) {
- v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_));
+ v->VisitPointer(BitCast<Object**, FixedArray**>(&cache_));
}
- bool Lookup(Vector<const char> name, Handle<JSFunction>* handle) {
+ bool Lookup(Vector<const char> name, Handle<SharedFunctionInfo>* handle) {
for (int i = 0; i < cache_->length(); i+=2) {
SeqAsciiString* str = SeqAsciiString::cast(cache_->get(i));
if (str->IsEqualTo(name)) {
- *handle = Handle<JSFunction>(JSFunction::cast(cache_->get(i + 1)));
+ *handle = Handle<SharedFunctionInfo>(
+ SharedFunctionInfo::cast(cache_->get(i + 1)));
return true;
}
}
@@ -71,8 +72,7 @@
}
- void Add(Vector<const char> name, Handle<JSFunction> fun) {
- ASSERT(fun->IsBoilerplate());
+ void Add(Vector<const char> name, Handle<SharedFunctionInfo> shared) {
HandleScope scope;
int length = cache_->length();
Handle<FixedArray> new_array =
@@ -81,8 +81,8 @@
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_));
+ cache_->set(length + 1, *shared);
+ Script::cast(shared->script())->set_type(Smi::FromInt(type_));
}
private:
@@ -228,6 +228,7 @@
// Used for creating a context from scratch.
void InstallNativeFunctions();
bool InstallNatives();
+ void InstallJSFunctionResultCaches();
// Used both for deserialized and from-scratch contexts to add the extensions
// provided.
static bool InstallExtensions(Handle<Context> global_context,
@@ -247,17 +248,15 @@
void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
+ enum PrototypePropertyMode {
+ DONT_ADD_PROTOTYPE,
+ ADD_READONLY_PROTOTYPE,
+ ADD_WRITEABLE_PROTOTYPE
+ };
Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
- bool make_prototype_read_only,
- bool make_prototype_enumerable = false);
+ PrototypePropertyMode prototypeMode);
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,
@@ -335,7 +334,8 @@
bool is_ecma_native) {
Handle<String> symbol = Factory::LookupAsciiSymbol(name);
Handle<Code> call_code = Handle<Code>(Builtins::builtin(call));
- Handle<JSFunction> function =
+ Handle<JSFunction> function = prototype.is_null() ?
+ Factory::NewFunctionWithoutPrototype(symbol, call_code) :
Factory::NewFunctionWithPrototype(symbol,
type,
instance_size,
@@ -351,23 +351,23 @@
Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
- bool make_prototype_read_only,
- bool make_prototype_enumerable) {
+ PrototypePropertyMode prototypeMode) {
Handle<DescriptorArray> result = Factory::empty_descriptor_array();
- // Add prototype.
- PropertyAttributes attributes = static_cast<PropertyAttributes>(
- (make_prototype_enumerable ? 0 : DONT_ENUM)
- | DONT_DELETE
- | (make_prototype_read_only ? READ_ONLY : 0));
- result =
- Factory::CopyAppendProxyDescriptor(
- result,
- Factory::prototype_symbol(),
- Factory::NewProxy(&Accessors::FunctionPrototype),
- attributes);
+ if (prototypeMode != DONT_ADD_PROTOTYPE) {
+ PropertyAttributes attributes = static_cast<PropertyAttributes>(
+ DONT_ENUM |
+ DONT_DELETE |
+ (prototypeMode == ADD_READONLY_PROTOTYPE ? READ_ONLY : 0));
+ result =
+ Factory::CopyAppendProxyDescriptor(
+ result,
+ Factory::prototype_symbol(),
+ Factory::NewProxy(&Accessors::FunctionPrototype),
+ attributes);
+ }
- attributes =
+ PropertyAttributes attributes =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
// Add length.
result =
@@ -412,14 +412,29 @@
// Please note that the prototype property for function instances must be
// writable.
Handle<DescriptorArray> function_map_descriptors =
- ComputeFunctionInstanceDescriptor(false, false);
+ ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE);
fm->set_instance_descriptors(*function_map_descriptors);
+ fm->set_function_with_prototype(true);
+
+ // Functions with this map will not have a 'prototype' property, and
+ // can not be used as constructors.
+ Handle<Map> function_without_prototype_map =
+ Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+ global_context()->set_function_without_prototype_map(
+ *function_without_prototype_map);
+ Handle<DescriptorArray> function_without_prototype_map_descriptors =
+ ComputeFunctionInstanceDescriptor(DONT_ADD_PROTOTYPE);
+ function_without_prototype_map->set_instance_descriptors(
+ *function_without_prototype_map_descriptors);
+ function_without_prototype_map->set_function_with_prototype(false);
// Allocate the function map first and then patch the prototype later
fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
global_context()->set_function_map(*fm);
- function_map_descriptors = ComputeFunctionInstanceDescriptor(true);
+ function_map_descriptors =
+ ComputeFunctionInstanceDescriptor(ADD_READONLY_PROTOTYPE);
fm->set_instance_descriptors(*function_map_descriptors);
+ fm->set_function_with_prototype(true);
Handle<String> object_name = Handle<String>(Heap::Object_symbol());
@@ -447,7 +462,7 @@
// 262 15.3.4.
Handle<String> symbol = Factory::LookupAsciiSymbol("Empty");
Handle<JSFunction> empty_function =
- Factory::NewFunction(symbol, Factory::null_value());
+ Factory::NewFunctionWithoutPrototype(symbol);
// --- E m p t y ---
Handle<Code> code =
@@ -462,10 +477,14 @@
empty_function->shared()->DontAdaptArguments();
global_context()->function_map()->set_prototype(*empty_function);
global_context()->function_instance_map()->set_prototype(*empty_function);
+ global_context()->function_without_prototype_map()->
+ set_prototype(*empty_function);
// Allocate the function map first and then patch the prototype later
- Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(fm);
- empty_fm->set_instance_descriptors(*function_map_descriptors);
+ Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(
+ function_without_prototype_map);
+ empty_fm->set_instance_descriptors(
+ *function_without_prototype_map_descriptors);
empty_fm->set_prototype(global_context()->object_function()->prototype());
empty_function->set_map(*empty_fm);
return empty_function;
@@ -729,8 +748,68 @@
InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
Top::initial_object_prototype(), Builtins::Illegal,
true);
-
global_context()->set_regexp_function(*regexp_fun);
+
+ ASSERT(regexp_fun->has_initial_map());
+ Handle<Map> initial_map(regexp_fun->initial_map());
+
+ ASSERT_EQ(0, initial_map->inobject_properties());
+
+ Handle<DescriptorArray> descriptors = Factory::NewDescriptorArray(5);
+ PropertyAttributes final =
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+ int enum_index = 0;
+ {
+ // ECMA-262, section 15.10.7.1.
+ FieldDescriptor field(Heap::source_symbol(),
+ JSRegExp::kSourceFieldIndex,
+ final,
+ enum_index++);
+ descriptors->Set(0, &field);
+ }
+ {
+ // ECMA-262, section 15.10.7.2.
+ FieldDescriptor field(Heap::global_symbol(),
+ JSRegExp::kGlobalFieldIndex,
+ final,
+ enum_index++);
+ descriptors->Set(1, &field);
+ }
+ {
+ // ECMA-262, section 15.10.7.3.
+ FieldDescriptor field(Heap::ignore_case_symbol(),
+ JSRegExp::kIgnoreCaseFieldIndex,
+ final,
+ enum_index++);
+ descriptors->Set(2, &field);
+ }
+ {
+ // ECMA-262, section 15.10.7.4.
+ FieldDescriptor field(Heap::multiline_symbol(),
+ JSRegExp::kMultilineFieldIndex,
+ final,
+ enum_index++);
+ descriptors->Set(3, &field);
+ }
+ {
+ // ECMA-262, section 15.10.7.5.
+ PropertyAttributes writable =
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
+ FieldDescriptor field(Heap::last_index_symbol(),
+ JSRegExp::kLastIndexFieldIndex,
+ writable,
+ enum_index++);
+ descriptors->Set(4, &field);
+ }
+ descriptors->SetNextEnumerationIndex(enum_index);
+ descriptors->Sort();
+
+ initial_map->set_inobject_properties(5);
+ initial_map->set_pre_allocated_property_fields(5);
+ initial_map->set_unused_property_fields(0);
+ initial_map->set_instance_size(
+ initial_map->instance_size() + 5 * kPointerSize);
+ initial_map->set_instance_descriptors(*descriptors);
}
{ // -- J S O N
@@ -835,8 +914,6 @@
delegate->shared()->DontAdaptArguments();
}
- global_context()->set_special_function_table(Heap::empty_fixed_array());
-
// Initialize the out of memory slot.
global_context()->set_out_of_memory(Heap::false_value());
@@ -879,14 +956,14 @@
Handle<Context> top_context,
bool use_runtime_context) {
HandleScope scope;
- Handle<JSFunction> boilerplate;
+ Handle<SharedFunctionInfo> function_info;
// If we can't find the function in the cache, we compile a new
// function and insert it into the cache.
- if (cache == NULL || !cache->Lookup(name, &boilerplate)) {
+ if (cache == NULL || !cache->Lookup(name, &function_info)) {
ASSERT(source->IsAsciiRepresentation());
Handle<String> script_name = Factory::NewStringFromUtf8(name);
- boilerplate = Compiler::Compile(
+ function_info = Compiler::Compile(
source,
script_name,
0,
@@ -895,8 +972,8 @@
NULL,
Handle<String>::null(),
use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
- if (boilerplate.is_null()) return false;
- if (cache != NULL) cache->Add(name, boilerplate);
+ if (function_info.is_null()) return false;
+ if (cache != NULL) cache->Add(name, function_info);
}
// Setup the function context. Conceptually, we should clone the
@@ -908,7 +985,7 @@
? Handle<Context>(top_context->runtime_context())
: top_context);
Handle<JSFunction> fun =
- Factory::NewFunctionFromBoilerplate(boilerplate, context);
+ Factory::NewFunctionFromSharedFunctionInfo(function_info, context);
// Call function using either the runtime object or the global
// object as the receiver. Provide no parameters.
@@ -1119,6 +1196,24 @@
script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
Heap::public_set_empty_script(*script);
}
+ {
+ // Builtin function for OpaqueReference -- a JSValue-based object,
+ // that keeps its field isolated from JavaScript code. It may store
+ // objects, that JavaScript code may not access.
+ Handle<JSFunction> opaque_reference_fun =
+ InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
+ JSValue::kSize, Top::initial_object_prototype(),
+ Builtins::Illegal, false);
+ Handle<JSObject> prototype =
+ Factory::NewJSObject(Top::object_function(), TENURED);
+ SetPrototype(opaque_reference_fun, prototype);
+ global_context()->set_opaque_reference_function(*opaque_reference_fun);
+ }
+
+ if (FLAG_disable_native_files) {
+ PrintF("Warning: Running without installed natives!\n");
+ return true;
+ }
// Install natives.
for (int i = Natives::GetDebuggerCount();
@@ -1144,12 +1239,12 @@
// Install the call and the apply functions.
Handle<JSFunction> call =
InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
- Factory::NewJSObject(Top::object_function(), TENURED),
+ Handle<JSObject>::null(),
Builtins::FunctionCall,
false);
Handle<JSFunction> apply =
InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
- Factory::NewJSObject(Top::object_function(), TENURED),
+ Handle<JSObject>::null(),
Builtins::FunctionApply,
false);
@@ -1167,6 +1262,62 @@
apply->shared()->set_length(2);
}
+ // Create a constructor for RegExp results (a variant of Array that
+ // predefines the two properties index and match).
+ {
+ // RegExpResult initial map.
+
+ // Find global.Array.prototype to inherit from.
+ Handle<JSFunction> array_constructor(global_context()->array_function());
+ Handle<JSObject> array_prototype(
+ JSObject::cast(array_constructor->instance_prototype()));
+
+ // Add initial map.
+ Handle<Map> initial_map =
+ Factory::NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
+ initial_map->set_constructor(*array_constructor);
+
+ // Set prototype on map.
+ initial_map->set_non_instance_prototype(false);
+ initial_map->set_prototype(*array_prototype);
+
+ // Update map with length accessor from Array and add "index" and "input".
+ Handle<Map> array_map(global_context()->js_array_map());
+ Handle<DescriptorArray> array_descriptors(
+ array_map->instance_descriptors());
+ ASSERT_EQ(1, array_descriptors->number_of_descriptors());
+
+ Handle<DescriptorArray> reresult_descriptors =
+ Factory::NewDescriptorArray(3);
+
+ reresult_descriptors->CopyFrom(0, *array_descriptors, 0);
+
+ int enum_index = 0;
+ {
+ FieldDescriptor index_field(Heap::index_symbol(),
+ JSRegExpResult::kIndexIndex,
+ NONE,
+ enum_index++);
+ reresult_descriptors->Set(1, &index_field);
+ }
+
+ {
+ FieldDescriptor input_field(Heap::input_symbol(),
+ JSRegExpResult::kInputIndex,
+ NONE,
+ enum_index++);
+ reresult_descriptors->Set(2, &input_field);
+ }
+ reresult_descriptors->Sort();
+
+ initial_map->set_inobject_properties(2);
+ initial_map->set_pre_allocated_property_fields(2);
+ initial_map->set_unused_property_fields(0);
+ initial_map->set_instance_descriptors(*reresult_descriptors);
+
+ global_context()->set_regexp_result_map(*initial_map);
+ }
+
#ifdef DEBUG
builtins->Verify();
#endif
@@ -1175,6 +1326,42 @@
}
+// Do not forget to update macros.py with named constant
+// of cache id.
+#define JSFUNCTION_RESULT_CACHE_LIST(F) \
+ F(16, global_context()->regexp_function())
+
+
+static FixedArray* CreateCache(int size, JSFunction* factory) {
+ // Caches are supposed to live for a long time, allocate in old space.
+ int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
+ // Cannot use cast as object is not fully initialized yet.
+ JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
+ *Factory::NewFixedArrayWithHoles(array_size, TENURED));
+ cache->set(JSFunctionResultCache::kFactoryIndex, factory);
+ cache->MakeZeroSize();
+ return cache;
+}
+
+
+void Genesis::InstallJSFunctionResultCaches() {
+ const int kNumberOfCaches = 0 +
+#define F(size, func) + 1
+ JSFUNCTION_RESULT_CACHE_LIST(F)
+#undef F
+ ;
+
+ Handle<FixedArray> caches = Factory::NewFixedArray(kNumberOfCaches, TENURED);
+
+ int index = 0;
+#define F(size, func) caches->set(index++, CreateCache(size, func));
+ JSFUNCTION_RESULT_CACHE_LIST(F)
+#undef F
+
+ global_context()->set_jsfunction_result_caches(*caches);
+}
+
+
int BootstrapperActive::nesting_ = 0;
@@ -1327,6 +1514,7 @@
Handle<SharedFunctionInfo> shared
= Handle<SharedFunctionInfo>(function->shared());
if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
+ builtins->set_javascript_builtin_code(id, shared->code());
}
return true;
}
@@ -1489,72 +1677,14 @@
HandleScope scope;
Handle<DescriptorArray> function_map_descriptors =
- ComputeFunctionInstanceDescriptor(false);
+ ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE);
Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map());
fm->set_instance_descriptors(*function_map_descriptors);
+ fm->set_function_with_prototype(true);
Top::context()->global_context()->set_function_map(*fm);
}
-void Genesis::AddSpecialFunction(Handle<JSObject> prototype,
- const char* name,
- Handle<Code> code) {
- Handle<String> key = Factory::LookupAsciiSymbol(name);
- Handle<Object> value = Handle<Object>(prototype->GetProperty(*key));
- if (value->IsJSFunction()) {
- Handle<JSFunction> optimized = Factory::NewFunction(key,
- JS_OBJECT_TYPE,
- JSObject::kHeaderSize,
- code,
- false);
- optimized->shared()->DontAdaptArguments();
- int len = global_context()->special_function_table()->length();
- Handle<FixedArray> new_array = Factory::NewFixedArray(len + 3);
- for (int index = 0; index < len; index++) {
- new_array->set(index,
- global_context()->special_function_table()->get(index));
- }
- new_array->set(len+0, *prototype);
- new_array->set(len+1, *value);
- new_array->set(len+2, *optimized);
- global_context()->set_special_function_table(*new_array);
- }
-}
-
-
-void Genesis::BuildSpecialFunctionTable() {
- HandleScope scope;
- Handle<JSObject> global = Handle<JSObject>(global_context()->global());
- // Add special versions for some Array.prototype functions.
- Handle<JSFunction> function =
- Handle<JSFunction>(
- JSFunction::cast(global->GetProperty(Heap::Array_symbol())));
- Handle<JSObject> visible_prototype =
- Handle<JSObject>(JSObject::cast(function->prototype()));
- // Remember to put those specializations on the hidden prototype if present.
- Handle<JSObject> special_prototype;
- Handle<Object> superproto(visible_prototype->GetPrototype());
- if (superproto->IsJSObject() &&
- JSObject::cast(*superproto)->map()->is_hidden_prototype()) {
- special_prototype = Handle<JSObject>::cast(superproto);
- } else {
- special_prototype = visible_prototype;
- }
- AddSpecialFunction(special_prototype, "pop",
- Handle<Code>(Builtins::builtin(Builtins::ArrayPop)));
- AddSpecialFunction(special_prototype, "push",
- Handle<Code>(Builtins::builtin(Builtins::ArrayPush)));
- AddSpecialFunction(special_prototype, "shift",
- Handle<Code>(Builtins::builtin(Builtins::ArrayShift)));
- AddSpecialFunction(special_prototype, "unshift",
- Handle<Code>(Builtins::builtin(Builtins::ArrayUnshift)));
- AddSpecialFunction(special_prototype, "slice",
- Handle<Code>(Builtins::builtin(Builtins::ArraySlice)));
- AddSpecialFunction(special_prototype, "splice",
- Handle<Code>(Builtins::builtin(Builtins::ArraySplice)));
-}
-
-
Genesis::Genesis(Handle<Object> global_object,
v8::Handle<v8::ObjectTemplate> global_template,
v8::ExtensionConfiguration* extensions) {
@@ -1597,9 +1727,9 @@
HookUpGlobalProxy(inner_global, global_proxy);
InitializeGlobal(inner_global, empty_function);
if (!InstallNatives()) return;
+ InstallJSFunctionResultCaches();
MakeFunctionInstancePrototypeWritable();
- BuildSpecialFunctionTable();
if (!ConfigureGlobalObjects(global_template)) return;
i::Counters::contexts_created_from_scratch.Increment();