Directly create API functions with readonly prototypes rather than converting. Remove...
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 9 May 2014 17:59:15 +0000 (17:59 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 9 May 2014 17:59:15 +0000 (17:59 +0000)
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
src/apinatives.js
src/bootstrapper.cc
src/contexts.h
src/factory.cc
src/factory.h
src/objects.cc
src/objects.h
src/runtime.cc
src/runtime.h
test/mjsunit/runtime-gen/functionsetreadonlyprototype.js [deleted file]

index f4ae71d..4839be8 100644 (file)
@@ -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;
index 0579caf..0b45b3f 100644 (file)
@@ -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) {
index c35120d..600571e 100644 (file)
@@ -451,6 +451,8 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
   // Later the map is replaced with writable prototype map, allocated below.
   Handle<Map> 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.
index f1aa380..5381337 100644 (file)
@@ -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,
index cfcb2f1..f4d356b 100644 (file)
@@ -1210,7 +1210,9 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> 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<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
 
 Handle<JSFunction> Factory::NewFunction(Handle<String> name,
                                         Handle<Code> code,
-                                        Handle<Object> prototype) {
-  Handle<JSFunction> result = NewFunction(
-      isolate()->sloppy_function_map(), name, 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();
+  Handle<JSFunction> result = NewFunction(map, name, code);
   result->set_prototype_or_initial_map(*prototype);
   return result;
 }
@@ -1242,9 +1247,11 @@ Handle<JSFunction> Factory::NewFunction(Handle<String> name,
                                         Handle<Code> code,
                                         Handle<Object> prototype,
                                         InstanceType type,
-                                        int instance_size) {
+                                        int instance_size,
+                                        bool read_only_prototype) {
   // Allocate the function
-  Handle<JSFunction> function = NewFunction(name, code, prototype);
+  Handle<JSFunction> function = NewFunction(
+      name, code, prototype, read_only_prototype);
 
   Handle<Map> initial_map = NewMap(
       type, instance_size, GetInitialFastElementsKind());
@@ -2101,7 +2108,8 @@ Handle<JSFunction> 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());
index 45d5401..2c658e8 100644 (file)
@@ -453,7 +453,8 @@ class Factory V8_FINAL {
 
   Handle<JSFunction> NewFunction(Handle<String> name,
                                  Handle<Code> code,
-                                 Handle<Object> prototype);
+                                 Handle<Object> prototype,
+                                 bool read_only_prototype = false);
   Handle<JSFunction> NewFunction(Handle<String> name);
   Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
                                                  Handle<Code> code);
@@ -467,7 +468,8 @@ class Factory V8_FINAL {
                                  Handle<Code> code,
                                  Handle<Object> prototype,
                                  InstanceType type,
-                                 int instance_size);
+                                 int instance_size,
+                                 bool read_only_prototype = false);
   Handle<JSFunction> NewFunction(Handle<String> name,
                                  Handle<Code> code,
                                  InstanceType type,
index 1b95d89..cdd90d9 100644 (file)
@@ -7562,7 +7562,7 @@ Handle<Map> Map::CopyForFreeze(Handle<Map> map) {
   Isolate* isolate = map->GetIsolate();
   Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
       handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN);
-  Handle<Map> new_map = Map::CopyReplaceDescriptors(
+  Handle<Map> new_map = CopyReplaceDescriptors(
       map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol());
   new_map->freeze();
   new_map->set_is_extensible(false);
index 9e20652..20f40b8 100644 (file)
@@ -6305,11 +6305,6 @@ class Map: public HeapObject {
   static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
                                           Descriptor* descriptor,
                                           TransitionFlag flag);
-  static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
-                                           Handle<DescriptorArray> descriptors,
-                                           Descriptor* descriptor,
-                                           int index,
-                                           TransitionFlag flag);
 
   MUST_USE_RESULT static MaybeHandle<Map> CopyWithField(
       Handle<Map> map,
@@ -6582,6 +6577,11 @@ class Map: public HeapObject {
       TransitionFlag flag,
       MaybeHandle<Name> maybe_name,
       SimpleTransitionFlag simple_flag = FULL_TRANSITION);
+  static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
+                                           Handle<DescriptorArray> descriptors,
+                                           Descriptor* descriptor,
+                                           int index,
+                                           TransitionFlag flag);
 
   static Handle<Map> CopyNormalized(Handle<Map> map,
                                     PropertyNormalizationMode mode,
index 4982606..3e8167a 100644 (file)
@@ -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<String> name = isolate->factory()->prototype_string();
-
-  if (function->HasFastProperties()) {
-    // Construct a new field descriptor with updated attributes.
-    Handle<DescriptorArray> 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<PropertyAttributes>(details.attributes() | READ_ONLY));
-
-    // Create a new map featuring the new field descriptors array.
-    Handle<Map> map = handle(function->map());
-    Handle<Map> 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<PropertyAttributes>(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);
index 38d2126..1c3b224 100644 (file)
@@ -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 (file)
index 49b5d74..0000000
+++ /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);