Commit 47dc8702 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[runtime] Don't swap function maps during bootstrapping.

... but use proper map for functions with readonly prototype from the start.

Bug: v8:6459
Change-Id: I432d4969822e7cc4c2ba83e103f550d1c4f2e234
Reviewed-on: https://chromium-review.googlesource.com/563199Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46487}
parent d9cb6135
This diff is collapsed.
......@@ -1514,9 +1514,17 @@ Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype,
LanguageMode language_mode) {
Handle<Map> map = is_strict(language_mode) ? isolate()->strict_function_map()
: isolate()->sloppy_function_map();
LanguageMode language_mode,
MutableMode prototype_mutability) {
Handle<Map> map;
if (prototype_mutability == MUTABLE) {
map = is_strict(language_mode) ? isolate()->strict_function_map()
: isolate()->sloppy_function_map();
} else {
map = is_strict(language_mode)
? isolate()->strict_function_with_readonly_prototype_map()
: isolate()->sloppy_function_with_readonly_prototype_map();
}
Handle<JSFunction> result = NewFunction(map, name, code);
result->set_prototype_or_initial_map(*prototype);
result->shared()->set_language_mode(language_mode);
......@@ -1526,10 +1534,11 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype,
InstanceType type, int instance_size,
LanguageMode language_mode) {
LanguageMode language_mode,
MutableMode prototype_mutability) {
// Allocate the function
Handle<JSFunction> function =
NewFunction(name, code, prototype, language_mode);
NewFunction(name, code, prototype, language_mode, prototype_mutability);
ElementsKind elements_kind =
type == JS_ARRAY_TYPE ? PACKED_SMI_ELEMENTS : HOLEY_SMI_ELEMENTS;
......@@ -2831,11 +2840,16 @@ Handle<String> Factory::ToPrimitiveHintString(ToPrimitiveHint hint) {
UNREACHABLE();
}
Handle<Map> Factory::CreateSloppyFunctionMap(FunctionMode function_mode) {
Handle<Map> Factory::CreateSloppyFunctionMap(
FunctionMode function_mode, MaybeHandle<JSFunction> maybe_empty_function) {
Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetFunctionInstanceDescriptor(map, function_mode);
map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
map->set_is_callable();
Handle<JSFunction> empty_function;
if (maybe_empty_function.ToHandle(&empty_function)) {
Map::SetPrototype(map, empty_function);
}
return map;
}
......
......@@ -601,7 +601,8 @@ class V8_EXPORT_PRIVATE Factory final {
PretenureFlag pretenure = TENURED);
Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype,
LanguageMode language_mode = SLOPPY);
LanguageMode language_mode = SLOPPY,
MutableMode prototype_mutability = MUTABLE);
Handle<JSFunction> NewFunction(Handle<String> name);
Handle<JSFunction> NewFunctionWithoutPrototype(
Handle<String> name, Handle<Code> code,
......@@ -627,7 +628,8 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype, InstanceType type,
int instance_size,
LanguageMode language_mode = SLOPPY);
LanguageMode language_mode = SLOPPY,
MutableMode prototype_mutability = MUTABLE);
Handle<JSFunction> NewFunction(Handle<String> name,
Handle<Code> code,
InstanceType type,
......@@ -767,7 +769,8 @@ class V8_EXPORT_PRIVATE Factory final {
function_mode == FUNCTION_WITH_READONLY_PROTOTYPE);
}
Handle<Map> CreateSloppyFunctionMap(FunctionMode function_mode);
Handle<Map> CreateSloppyFunctionMap(
FunctionMode function_mode, MaybeHandle<JSFunction> maybe_empty_function);
Handle<Map> CreateStrictFunctionMap(FunctionMode function_mode,
Handle<JSFunction> empty_function);
......
......@@ -1502,7 +1502,7 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) {
Factory* factory = isolate->factory();
Handle<String> name = factory->empty_string();
Handle<Map> sloppy_map =
factory->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
Map::CopyInitialMap(isolate->sloppy_function_map());
Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfo(
name, MaybeHandle<Code>(), sloppy_map->is_constructor());
function_type_ = FieldType::Class(sloppy_map, isolate);
......@@ -2640,8 +2640,7 @@ TEST(TransitionDataConstantToAnotherDataConstant) {
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Handle<String> name = factory->empty_string();
Handle<Map> sloppy_map =
factory->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
Handle<Map> sloppy_map = Map::CopyInitialMap(isolate->sloppy_function_map());
Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfo(
name, MaybeHandle<Code>(), sloppy_map->is_constructor());
Handle<FieldType> function_type = FieldType::Class(sloppy_map, isolate);
......
......@@ -3,6 +3,19 @@
// found in the LICENSE file.
function CheckNoPrototype(object) {
var desc = Object.getOwnPropertyDescriptor(object, "prototype");
assertEquals(undefined, desc);
}
function CheckReadonlyPrototype(object) {
var desc = Object.getOwnPropertyDescriptor(object, "prototype");
assertTrue(desc != undefined);
assertFalse(desc.enumerable);
assertFalse(desc.configurable);
assertFalse(desc.writable);
}
function CheckMethodEx(object, prop_name, function_name, length) {
var desc = Object.getOwnPropertyDescriptor(object, prop_name);
assertTrue(desc != undefined);
......@@ -41,23 +54,54 @@ function CheckGetter(object, name) {
}
(function TestIntrinsicConstructors() {
CheckReadonlyPrototype(Object);
CheckReadonlyPrototype(Function);
CheckReadonlyPrototype(Number);
CheckReadonlyPrototype(Boolean);
CheckReadonlyPrototype(Symbol);
CheckReadonlyPrototype(Date);
CheckReadonlyPrototype(RegExp);
CheckReadonlyPrototype(DataView);
CheckReadonlyPrototype(ArrayBuffer);
var AsyncFunction = (async function(){}).constructor;
CheckReadonlyPrototype(AsyncFunction);
var GeneratorFunction = (function*(){}).constructor;
CheckReadonlyPrototype(GeneratorFunction);
CheckReadonlyPrototype(Error);
CheckReadonlyPrototype(SyntaxError);
CheckReadonlyPrototype(RangeError);
CheckReadonlyPrototype(TypeError);
CheckReadonlyPrototype(ReferenceError);
CheckReadonlyPrototype(EvalError);
CheckReadonlyPrototype(URIError);
CheckReadonlyPrototype(Error);
})();
(function TestIntl() {
if (typeof (Intl) == "undefined") return;
CheckMethod(Intl, "getCanonicalLocales", 1);
CheckReadonlyPrototype(Intl.Collator);
CheckMethod(Intl.Collator, "supportedLocalesOf", 1);
CheckGetter(Intl.Collator.prototype, "compare");
CheckMethod(Intl.Collator.prototype, "resolvedOptions", 0);
CheckReadonlyPrototype(Intl.NumberFormat);
CheckMethod(Intl.NumberFormat, "supportedLocalesOf", 1);
CheckGetter(Intl.NumberFormat.prototype, "format");
CheckMethod(Intl.NumberFormat.prototype, "resolvedOptions", 0);
CheckReadonlyPrototype(Intl.DateTimeFormat);
CheckMethod(Intl.DateTimeFormat, "supportedLocalesOf", 1);
CheckGetter(Intl.DateTimeFormat.prototype, "format");
CheckMethod(Intl.DateTimeFormat.prototype, "resolvedOptions", 0);
CheckMethod(Intl.DateTimeFormat.prototype, "formatToParts", 1);
CheckReadonlyPrototype(Intl.v8BreakIterator);
CheckMethod(Intl.v8BreakIterator, "supportedLocalesOf", 1);
CheckMethod(Intl.v8BreakIterator.prototype, "resolvedOptions", 0);
CheckGetter(Intl.v8BreakIterator.prototype, "adoptText");
......@@ -79,6 +123,7 @@ function CheckGetter(object, name) {
(function TestCollection() {
CheckReadonlyPrototype(Set);
CheckMethod(Set.prototype, "add", 1);
CheckMethod(Set.prototype, "delete", 1);
CheckMethod(Set.prototype, "entries", 0);
......@@ -93,6 +138,7 @@ function CheckGetter(object, name) {
undefined,
Object.getOwnPropertyDescriptor(SetIteratorPrototype, "constructor"));
CheckReadonlyPrototype(Map);
CheckMethod(Map.prototype, "set", 2);
CheckMethod(Map.prototype, "delete", 1);
CheckMethod(Map.prototype, "entries", 0);
......@@ -107,11 +153,13 @@ function CheckGetter(object, name) {
undefined,
Object.getOwnPropertyDescriptor(MapIteratorPrototype, "constructor"));
CheckReadonlyPrototype(WeakSet);
assertEquals(0, WeakSet.length);
CheckMethod(WeakSet.prototype, "add", 1);
CheckMethod(WeakSet.prototype, "delete", 1);
CheckMethod(WeakSet.prototype, "has", 1);
CheckReadonlyPrototype(WeakMap);
assertEquals(0, WeakMap.length);
CheckMethod(WeakMap.prototype, "delete", 1);
CheckMethod(WeakMap.prototype, "get", 1);
......@@ -123,6 +171,17 @@ function CheckGetter(object, name) {
(function TestTypedArrays() {
var TypedArray = Uint8Array.__proto__;
CheckReadonlyPrototype(Int8Array);
CheckReadonlyPrototype(Uint8Array);
CheckReadonlyPrototype(Uint8ClampedArray);
CheckReadonlyPrototype(Int16Array);
CheckReadonlyPrototype(Uint16Array);
CheckReadonlyPrototype(Int32Array);
CheckReadonlyPrototype(Uint32Array);
CheckReadonlyPrototype(Float32Array);
CheckReadonlyPrototype(Float64Array);
CheckReadonlyPrototype(TypedArray);
CheckMethod(TypedArray, "of", 0);
CheckMethod(TypedArray, "from", 1);
......@@ -139,6 +198,8 @@ function CheckGetter(object, name) {
(function TestArray() {
CheckReadonlyPrototype(Array);
CheckMethod(Array, "of", 0);
CheckMethod(Array, "from", 1);
......@@ -176,16 +237,22 @@ function CheckGetter(object, name) {
(function TestPromise() {
CheckReadonlyPrototype(Promise);
CheckMethod(Promise, "all", 1);
CheckMethod(Promise, "race", 1);
CheckMethod(Promise, "reject", 1);
CheckMethod(Promise, "resolve", 1);
})();
(function TestProxy() {
CheckNoPrototype(Proxy);
CheckMethod(Proxy, "revocable", 2);
})();
(function TestString() {
CheckReadonlyPrototype(String);
CheckMethod(String, "raw", 1);
CheckMethod(String.prototype, "codePointAt", 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment