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( ...@@ -1514,9 +1514,17 @@ Handle<JSFunction> Factory::NewFunctionWithoutPrototype(
Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code, Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype, Handle<Object> prototype,
LanguageMode language_mode) { LanguageMode language_mode,
Handle<Map> map = is_strict(language_mode) ? isolate()->strict_function_map() MutableMode prototype_mutability) {
: isolate()->sloppy_function_map(); 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); Handle<JSFunction> result = NewFunction(map, name, code);
result->set_prototype_or_initial_map(*prototype); result->set_prototype_or_initial_map(*prototype);
result->shared()->set_language_mode(language_mode); result->shared()->set_language_mode(language_mode);
...@@ -1526,10 +1534,11 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code, ...@@ -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<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype, Handle<Object> prototype,
InstanceType type, int instance_size, InstanceType type, int instance_size,
LanguageMode language_mode) { LanguageMode language_mode,
MutableMode prototype_mutability) {
// Allocate the function // Allocate the function
Handle<JSFunction> function = Handle<JSFunction> function =
NewFunction(name, code, prototype, language_mode); NewFunction(name, code, prototype, language_mode, prototype_mutability);
ElementsKind elements_kind = ElementsKind elements_kind =
type == JS_ARRAY_TYPE ? PACKED_SMI_ELEMENTS : HOLEY_SMI_ELEMENTS; type == JS_ARRAY_TYPE ? PACKED_SMI_ELEMENTS : HOLEY_SMI_ELEMENTS;
...@@ -2831,11 +2840,16 @@ Handle<String> Factory::ToPrimitiveHintString(ToPrimitiveHint hint) { ...@@ -2831,11 +2840,16 @@ Handle<String> Factory::ToPrimitiveHintString(ToPrimitiveHint hint) {
UNREACHABLE(); 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); Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetFunctionInstanceDescriptor(map, function_mode); SetFunctionInstanceDescriptor(map, function_mode);
map->set_is_constructor(IsFunctionModeWithPrototype(function_mode)); map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
map->set_is_callable(); map->set_is_callable();
Handle<JSFunction> empty_function;
if (maybe_empty_function.ToHandle(&empty_function)) {
Map::SetPrototype(map, empty_function);
}
return map; return map;
} }
......
...@@ -601,7 +601,8 @@ class V8_EXPORT_PRIVATE Factory final { ...@@ -601,7 +601,8 @@ class V8_EXPORT_PRIVATE Factory final {
PretenureFlag pretenure = TENURED); PretenureFlag pretenure = TENURED);
Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code, Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype, Handle<Object> prototype,
LanguageMode language_mode = SLOPPY); LanguageMode language_mode = SLOPPY,
MutableMode prototype_mutability = MUTABLE);
Handle<JSFunction> NewFunction(Handle<String> name); Handle<JSFunction> NewFunction(Handle<String> name);
Handle<JSFunction> NewFunctionWithoutPrototype( Handle<JSFunction> NewFunctionWithoutPrototype(
Handle<String> name, Handle<Code> code, Handle<String> name, Handle<Code> code,
...@@ -627,7 +628,8 @@ class V8_EXPORT_PRIVATE Factory final { ...@@ -627,7 +628,8 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code, Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype, InstanceType type, Handle<Object> prototype, InstanceType type,
int instance_size, int instance_size,
LanguageMode language_mode = SLOPPY); LanguageMode language_mode = SLOPPY,
MutableMode prototype_mutability = MUTABLE);
Handle<JSFunction> NewFunction(Handle<String> name, Handle<JSFunction> NewFunction(Handle<String> name,
Handle<Code> code, Handle<Code> code,
InstanceType type, InstanceType type,
...@@ -767,7 +769,8 @@ class V8_EXPORT_PRIVATE Factory final { ...@@ -767,7 +769,8 @@ class V8_EXPORT_PRIVATE Factory final {
function_mode == FUNCTION_WITH_READONLY_PROTOTYPE); 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<Map> CreateStrictFunctionMap(FunctionMode function_mode,
Handle<JSFunction> empty_function); Handle<JSFunction> empty_function);
......
...@@ -1502,7 +1502,7 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) { ...@@ -1502,7 +1502,7 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Handle<String> name = factory->empty_string(); Handle<String> name = factory->empty_string();
Handle<Map> sloppy_map = Handle<Map> sloppy_map =
factory->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE); Map::CopyInitialMap(isolate->sloppy_function_map());
Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfo( Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfo(
name, MaybeHandle<Code>(), sloppy_map->is_constructor()); name, MaybeHandle<Code>(), sloppy_map->is_constructor());
function_type_ = FieldType::Class(sloppy_map, isolate); function_type_ = FieldType::Class(sloppy_map, isolate);
...@@ -2640,8 +2640,7 @@ TEST(TransitionDataConstantToAnotherDataConstant) { ...@@ -2640,8 +2640,7 @@ TEST(TransitionDataConstantToAnotherDataConstant) {
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Handle<String> name = factory->empty_string(); Handle<String> name = factory->empty_string();
Handle<Map> sloppy_map = Handle<Map> sloppy_map = Map::CopyInitialMap(isolate->sloppy_function_map());
factory->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfo( Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfo(
name, MaybeHandle<Code>(), sloppy_map->is_constructor()); name, MaybeHandle<Code>(), sloppy_map->is_constructor());
Handle<FieldType> function_type = FieldType::Class(sloppy_map, isolate); Handle<FieldType> function_type = FieldType::Class(sloppy_map, isolate);
......
...@@ -3,6 +3,19 @@ ...@@ -3,6 +3,19 @@
// found in the LICENSE file. // 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) { function CheckMethodEx(object, prop_name, function_name, length) {
var desc = Object.getOwnPropertyDescriptor(object, prop_name); var desc = Object.getOwnPropertyDescriptor(object, prop_name);
assertTrue(desc != undefined); assertTrue(desc != undefined);
...@@ -41,23 +54,54 @@ function CheckGetter(object, name) { ...@@ -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() { (function TestIntl() {
if (typeof (Intl) == "undefined") return; if (typeof (Intl) == "undefined") return;
CheckMethod(Intl, "getCanonicalLocales", 1); CheckMethod(Intl, "getCanonicalLocales", 1);
CheckReadonlyPrototype(Intl.Collator);
CheckMethod(Intl.Collator, "supportedLocalesOf", 1); CheckMethod(Intl.Collator, "supportedLocalesOf", 1);
CheckGetter(Intl.Collator.prototype, "compare"); CheckGetter(Intl.Collator.prototype, "compare");
CheckMethod(Intl.Collator.prototype, "resolvedOptions", 0); CheckMethod(Intl.Collator.prototype, "resolvedOptions", 0);
CheckReadonlyPrototype(Intl.NumberFormat);
CheckMethod(Intl.NumberFormat, "supportedLocalesOf", 1); CheckMethod(Intl.NumberFormat, "supportedLocalesOf", 1);
CheckGetter(Intl.NumberFormat.prototype, "format"); CheckGetter(Intl.NumberFormat.prototype, "format");
CheckMethod(Intl.NumberFormat.prototype, "resolvedOptions", 0); CheckMethod(Intl.NumberFormat.prototype, "resolvedOptions", 0);
CheckReadonlyPrototype(Intl.DateTimeFormat);
CheckMethod(Intl.DateTimeFormat, "supportedLocalesOf", 1); CheckMethod(Intl.DateTimeFormat, "supportedLocalesOf", 1);
CheckGetter(Intl.DateTimeFormat.prototype, "format"); CheckGetter(Intl.DateTimeFormat.prototype, "format");
CheckMethod(Intl.DateTimeFormat.prototype, "resolvedOptions", 0); CheckMethod(Intl.DateTimeFormat.prototype, "resolvedOptions", 0);
CheckMethod(Intl.DateTimeFormat.prototype, "formatToParts", 1); CheckMethod(Intl.DateTimeFormat.prototype, "formatToParts", 1);
CheckReadonlyPrototype(Intl.v8BreakIterator);
CheckMethod(Intl.v8BreakIterator, "supportedLocalesOf", 1); CheckMethod(Intl.v8BreakIterator, "supportedLocalesOf", 1);
CheckMethod(Intl.v8BreakIterator.prototype, "resolvedOptions", 0); CheckMethod(Intl.v8BreakIterator.prototype, "resolvedOptions", 0);
CheckGetter(Intl.v8BreakIterator.prototype, "adoptText"); CheckGetter(Intl.v8BreakIterator.prototype, "adoptText");
...@@ -79,6 +123,7 @@ function CheckGetter(object, name) { ...@@ -79,6 +123,7 @@ function CheckGetter(object, name) {
(function TestCollection() { (function TestCollection() {
CheckReadonlyPrototype(Set);
CheckMethod(Set.prototype, "add", 1); CheckMethod(Set.prototype, "add", 1);
CheckMethod(Set.prototype, "delete", 1); CheckMethod(Set.prototype, "delete", 1);
CheckMethod(Set.prototype, "entries", 0); CheckMethod(Set.prototype, "entries", 0);
...@@ -93,6 +138,7 @@ function CheckGetter(object, name) { ...@@ -93,6 +138,7 @@ function CheckGetter(object, name) {
undefined, undefined,
Object.getOwnPropertyDescriptor(SetIteratorPrototype, "constructor")); Object.getOwnPropertyDescriptor(SetIteratorPrototype, "constructor"));
CheckReadonlyPrototype(Map);
CheckMethod(Map.prototype, "set", 2); CheckMethod(Map.prototype, "set", 2);
CheckMethod(Map.prototype, "delete", 1); CheckMethod(Map.prototype, "delete", 1);
CheckMethod(Map.prototype, "entries", 0); CheckMethod(Map.prototype, "entries", 0);
...@@ -107,11 +153,13 @@ function CheckGetter(object, name) { ...@@ -107,11 +153,13 @@ function CheckGetter(object, name) {
undefined, undefined,
Object.getOwnPropertyDescriptor(MapIteratorPrototype, "constructor")); Object.getOwnPropertyDescriptor(MapIteratorPrototype, "constructor"));
CheckReadonlyPrototype(WeakSet);
assertEquals(0, WeakSet.length); assertEquals(0, WeakSet.length);
CheckMethod(WeakSet.prototype, "add", 1); CheckMethod(WeakSet.prototype, "add", 1);
CheckMethod(WeakSet.prototype, "delete", 1); CheckMethod(WeakSet.prototype, "delete", 1);
CheckMethod(WeakSet.prototype, "has", 1); CheckMethod(WeakSet.prototype, "has", 1);
CheckReadonlyPrototype(WeakMap);
assertEquals(0, WeakMap.length); assertEquals(0, WeakMap.length);
CheckMethod(WeakMap.prototype, "delete", 1); CheckMethod(WeakMap.prototype, "delete", 1);
CheckMethod(WeakMap.prototype, "get", 1); CheckMethod(WeakMap.prototype, "get", 1);
...@@ -123,6 +171,17 @@ function CheckGetter(object, name) { ...@@ -123,6 +171,17 @@ function CheckGetter(object, name) {
(function TestTypedArrays() { (function TestTypedArrays() {
var TypedArray = Uint8Array.__proto__; 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, "of", 0);
CheckMethod(TypedArray, "from", 1); CheckMethod(TypedArray, "from", 1);
...@@ -139,6 +198,8 @@ function CheckGetter(object, name) { ...@@ -139,6 +198,8 @@ function CheckGetter(object, name) {
(function TestArray() { (function TestArray() {
CheckReadonlyPrototype(Array);
CheckMethod(Array, "of", 0); CheckMethod(Array, "of", 0);
CheckMethod(Array, "from", 1); CheckMethod(Array, "from", 1);
...@@ -176,16 +237,22 @@ function CheckGetter(object, name) { ...@@ -176,16 +237,22 @@ function CheckGetter(object, name) {
(function TestPromise() { (function TestPromise() {
CheckReadonlyPrototype(Promise);
CheckMethod(Promise, "all", 1);
CheckMethod(Promise, "race", 1); CheckMethod(Promise, "race", 1);
CheckMethod(Promise, "reject", 1);
CheckMethod(Promise, "resolve", 1);
})(); })();
(function TestProxy() { (function TestProxy() {
CheckNoPrototype(Proxy);
CheckMethod(Proxy, "revocable", 2); CheckMethod(Proxy, "revocable", 2);
})(); })();
(function TestString() { (function TestString() {
CheckReadonlyPrototype(String);
CheckMethod(String, "raw", 1); CheckMethod(String, "raw", 1);
CheckMethod(String.prototype, "codePointAt", 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