From 03905e47536563435039a407cd90d0e4707a18c4 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Fri, 9 May 2014 17:59:15 +0000 Subject: [PATCH] Directly create API functions with readonly prototypes rather than converting. Remove FunctionSetReadOnlyPrototype. BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/274463003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21243 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 2 +- src/apinatives.js | 6 +-- src/bootstrapper.cc | 2 + src/contexts.h | 3 ++ src/factory.cc | 22 +++++++---- src/factory.h | 6 ++- src/objects.cc | 2 +- src/objects.h | 10 ++--- src/runtime.cc | 43 ---------------------- src/runtime.h | 1 - .../runtime-gen/functionsetreadonlyprototype.js | 5 --- 11 files changed, 32 insertions(+), 70 deletions(-) delete mode 100644 test/mjsunit/runtime-gen/functionsetreadonlyprototype.js diff --git a/include/v8.h b/include/v8.h index f4ae71d..4839be8 100644 --- a/include/v8.h +++ b/include/v8.h @@ -5530,7 +5530,7 @@ class Internals { static const int kJSObjectHeaderSize = 3 * kApiPointerSize; static const int kFixedArrayHeaderSize = 2 * kApiPointerSize; static const int kContextHeaderSize = 2 * kApiPointerSize; - static const int kContextEmbedderDataIndex = 74; + static const int kContextEmbedderDataIndex = 75; static const int kFullStringRepresentationMask = 0x07; static const int kStringEncodingMask = 0x4; static const int kExternalTwoByteRepresentationTag = 0x02; diff --git a/src/apinatives.js b/src/apinatives.js index 0579caf..0b45b3f 100644 --- a/src/apinatives.js +++ b/src/apinatives.js @@ -49,9 +49,8 @@ function InstantiateFunction(data, name) { if (!isFunctionCached) { try { var flags = %GetTemplateField(data, kApiFlagOffset); - var has_proto = !(flags & (1 << kRemovePrototypeBit)); var prototype; - if (has_proto) { + if (!(flags & (1 << kRemovePrototypeBit))) { var template = %GetTemplateField(data, kApiPrototypeTemplateOffset); prototype = typeof template === 'undefined' ? {} : Instantiate(template); @@ -68,9 +67,6 @@ function InstantiateFunction(data, name) { if (name) %FunctionSetName(fun, name); var doNotCache = flags & (1 << kDoNotCacheBit); if (!doNotCache) cache[serialNumber] = fun; - if (has_proto && flags & (1 << kReadOnlyPrototypeBit)) { - %FunctionSetReadOnlyPrototype(fun); - } ConfigureTemplateInstance(fun, data); if (doNotCache) return fun; } catch (e) { diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index c35120d..600571e 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -451,6 +451,8 @@ Handle Genesis::CreateEmptyFunction(Isolate* isolate) { // Later the map is replaced with writable prototype map, allocated below. Handle function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE); native_context()->set_sloppy_function_map(*function_map); + native_context()->set_sloppy_function_with_readonly_prototype_map( + *function_map); // The final map for functions. Writeable prototype. // This map is installed in MakeFunctionInstancePrototypeWritable. diff --git a/src/contexts.h b/src/contexts.h index f1aa380..5381337 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -123,6 +123,8 @@ enum BindingFlags { uint8_clamped_array_external_map) \ V(DATA_VIEW_FUN_INDEX, JSFunction, data_view_fun) \ V(SLOPPY_FUNCTION_MAP_INDEX, Map, sloppy_function_map) \ + V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \ + sloppy_function_with_readonly_prototype_map) \ V(STRICT_FUNCTION_MAP_INDEX, Map, strict_function_map) \ V(SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, Map, \ sloppy_function_without_prototype_map) \ @@ -265,6 +267,7 @@ class Context: public FixedArray { STRICT_ARGUMENTS_BOILERPLATE_INDEX, REGEXP_RESULT_MAP_INDEX, SLOPPY_FUNCTION_MAP_INDEX, + SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, STRICT_FUNCTION_MAP_INDEX, SLOPPY_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, diff --git a/src/factory.cc b/src/factory.cc index cfcb2f1..f4d356b 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -1210,7 +1210,9 @@ Handle Factory::NewFunction(Handle map, ASSERT((info->strict_mode() == SLOPPY) && (map.is_identical_to(isolate()->sloppy_function_map()) || map.is_identical_to( - isolate()->sloppy_function_without_prototype_map()))); + isolate()->sloppy_function_without_prototype_map()) || + map.is_identical_to( + isolate()->sloppy_function_with_readonly_prototype_map()))); return NewFunction(map, info, context); } @@ -1230,9 +1232,12 @@ Handle Factory::NewFunctionWithoutPrototype(Handle name, Handle Factory::NewFunction(Handle name, Handle code, - Handle prototype) { - Handle result = NewFunction( - isolate()->sloppy_function_map(), name, code); + Handle prototype, + bool read_only_prototype) { + Handle map = read_only_prototype + ? isolate()->sloppy_function_with_readonly_prototype_map() + : isolate()->sloppy_function_map(); + Handle result = NewFunction(map, name, code); result->set_prototype_or_initial_map(*prototype); return result; } @@ -1242,9 +1247,11 @@ Handle Factory::NewFunction(Handle name, Handle code, Handle prototype, InstanceType type, - int instance_size) { + int instance_size, + bool read_only_prototype) { // Allocate the function - Handle function = NewFunction(name, code, prototype); + Handle function = NewFunction( + name, code, prototype, read_only_prototype); Handle initial_map = NewMap( type, instance_size, GetInitialFastElementsKind()); @@ -2101,7 +2108,8 @@ Handle Factory::CreateApiFunction( break; } - result = NewFunction(empty_string(), code, prototype, type, instance_size); + result = NewFunction(empty_string(), code, prototype, type, + instance_size, obj->read_only_prototype()); } result->shared()->set_length(obj->length()); diff --git a/src/factory.h b/src/factory.h index 45d5401..2c658e8 100644 --- a/src/factory.h +++ b/src/factory.h @@ -453,7 +453,8 @@ class Factory V8_FINAL { Handle NewFunction(Handle name, Handle code, - Handle prototype); + Handle prototype, + bool read_only_prototype = false); Handle NewFunction(Handle name); Handle NewFunctionWithoutPrototype(Handle name, Handle code); @@ -467,7 +468,8 @@ class Factory V8_FINAL { Handle code, Handle prototype, InstanceType type, - int instance_size); + int instance_size, + bool read_only_prototype = false); Handle NewFunction(Handle name, Handle code, InstanceType type, diff --git a/src/objects.cc b/src/objects.cc index 1b95d89..cdd90d9 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -7562,7 +7562,7 @@ Handle Map::CopyForFreeze(Handle map) { Isolate* isolate = map->GetIsolate(); Handle new_desc = DescriptorArray::CopyUpToAddAttributes( handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN); - Handle new_map = Map::CopyReplaceDescriptors( + Handle new_map = CopyReplaceDescriptors( map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol()); new_map->freeze(); new_map->set_is_extensible(false); diff --git a/src/objects.h b/src/objects.h index 9e20652..20f40b8 100644 --- a/src/objects.h +++ b/src/objects.h @@ -6305,11 +6305,6 @@ class Map: public HeapObject { static Handle CopyInsertDescriptor(Handle map, Descriptor* descriptor, TransitionFlag flag); - static Handle CopyReplaceDescriptor(Handle map, - Handle descriptors, - Descriptor* descriptor, - int index, - TransitionFlag flag); MUST_USE_RESULT static MaybeHandle CopyWithField( Handle map, @@ -6582,6 +6577,11 @@ class Map: public HeapObject { TransitionFlag flag, MaybeHandle maybe_name, SimpleTransitionFlag simple_flag = FULL_TRANSITION); + static Handle CopyReplaceDescriptor(Handle map, + Handle descriptors, + Descriptor* descriptor, + int index, + TransitionFlag flag); static Handle CopyNormalized(Handle map, PropertyNormalizationMode mode, diff --git a/src/runtime.cc b/src/runtime.cc index 4982606..3e8167a 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -3042,49 +3042,6 @@ RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) { } -RUNTIME_FUNCTION(Runtime_FunctionSetReadOnlyPrototype) { - HandleScope shs(isolate); - RUNTIME_ASSERT(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); - - Handle name = isolate->factory()->prototype_string(); - - if (function->HasFastProperties()) { - // Construct a new field descriptor with updated attributes. - Handle instance_desc = - handle(function->map()->instance_descriptors()); - - int index = instance_desc->SearchWithCache(*name, function->map()); - ASSERT(index != DescriptorArray::kNotFound); - PropertyDetails details = instance_desc->GetDetails(index); - - CallbacksDescriptor new_desc( - name, - handle(instance_desc->GetValue(index), isolate), - static_cast(details.attributes() | READ_ONLY)); - - // Create a new map featuring the new field descriptors array. - Handle map = handle(function->map()); - Handle new_map = Map::CopyReplaceDescriptor( - map, instance_desc, &new_desc, index, OMIT_TRANSITION); - - JSObject::MigrateToMap(function, new_map); - } else { // Dictionary properties. - // Directly manipulate the property details. - DisallowHeapAllocation no_gc; - int entry = function->property_dictionary()->FindEntry(name); - ASSERT(entry != NameDictionary::kNotFound); - PropertyDetails details = function->property_dictionary()->DetailsAt(entry); - PropertyDetails new_details( - static_cast(details.attributes() | READ_ONLY), - details.type(), - details.dictionary_index()); - function->property_dictionary()->DetailsAtPut(entry, new_details); - } - return *function; -} - - RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) { SealHandleScope shs(isolate); ASSERT(args.length() == 1); diff --git a/src/runtime.h b/src/runtime.h index 38d2126..1c3b224 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -180,7 +180,6 @@ namespace internal { F(FunctionSetInstanceClassName, 2, 1) \ F(FunctionSetLength, 2, 1) \ F(FunctionSetPrototype, 2, 1) \ - F(FunctionSetReadOnlyPrototype, 1, 1) \ F(FunctionGetName, 1, 1) \ F(FunctionSetName, 2, 1) \ F(FunctionNameShouldPrintAsAnonymous, 1, 1) \ diff --git a/test/mjsunit/runtime-gen/functionsetreadonlyprototype.js b/test/mjsunit/runtime-gen/functionsetreadonlyprototype.js deleted file mode 100644 index 49b5d74..0000000 --- a/test/mjsunit/runtime-gen/functionsetreadonlyprototype.js +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY -// Flags: --allow-natives-syntax --harmony -var _function = function() {}; -%FunctionSetReadOnlyPrototype(_function); -- 2.7.4