[runtime] Store constructor function index on primitive maps.
authorbmeurer <bmeurer@chromium.org>
Tue, 11 Aug 2015 19:36:04 +0000 (12:36 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 11 Aug 2015 19:36:14 +0000 (19:36 +0000)
This way we can greatly simplify the different variants of ToObject in
our codebase and make them more uniform and robust.  Adding a new
primitive doesn't require finding and changing all those places again,
but it is sufficient to setup the constructor function index when
allocating the map.

We use the inobject properties field of Map, which is invalid primitive
maps anyway.

R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/1276533003

Cr-Commit-Position: refs/heads/master@{#30119}

29 files changed:
src/arm/builtins-arm.cc
src/arm64/builtins-arm64.cc
src/bootstrapper.cc
src/factory.cc
src/field-index-inl.h
src/heap/heap.cc
src/heap/objects-visiting-inl.h
src/hydrogen-instructions.h
src/hydrogen.cc
src/hydrogen.h
src/ia32/builtins-ia32.cc
src/ic/handler-compiler.cc
src/ic/ic-inl.h
src/layout-descriptor-inl.h
src/layout-descriptor.cc
src/mips/builtins-mips.cc
src/mips64/builtins-mips64.cc
src/objects-debug.cc
src/objects-inl.h
src/objects-printer.cc
src/objects.cc
src/objects.h
src/ppc/builtins-ppc.cc
src/runtime/runtime-collections.cc
src/runtime/runtime-object.cc
src/x64/builtins-x64.cc
src/x87/builtins-x87.cc
test/cctest/test-heap.cc
test/cctest/test-unboxed-doubles.cc

index 9a68c8dcb336d2f27334e64ceb322e4b8dd5d147..441f57e412a66b845e93582cf0eae2fe979d3954 100644 (file)
@@ -442,7 +442,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
 
         // Allocate object with a slack.
         __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset));
 
         // Allocate object with a slack.
         __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset));
-        __ Ubfx(r0, r0, Map::kInObjectPropertiesByte * kBitsPerByte,
+        __ Ubfx(r0, r0, Map::kInObjectPropertiesOrConstructorFunctionIndexByte *
+                            kBitsPerByte,
                 kBitsPerByte);
         __ ldr(r2, FieldMemOperand(r2, Map::kInstanceAttributesOffset));
         __ Ubfx(r2, r2, Map::kUnusedPropertyFieldsByte * kBitsPerByte,
                 kBitsPerByte);
         __ ldr(r2, FieldMemOperand(r2, Map::kInstanceAttributesOffset));
         __ Ubfx(r2, r2, Map::kUnusedPropertyFieldsByte * kBitsPerByte,
index c147a196c6d1da6eb6dfee09878b501a649c94b2..59b55a9f9f612a25232f712a1f50f29799d516a6 100644 (file)
@@ -436,8 +436,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
               Map::kUnusedPropertyFieldsByte * kBitsPerByte, kBitsPerByte);
       __ Ldr(inst_sizes_or_attrs,
              FieldMemOperand(init_map, Map::kInstanceSizesOffset));
               Map::kUnusedPropertyFieldsByte * kBitsPerByte, kBitsPerByte);
       __ Ldr(inst_sizes_or_attrs,
              FieldMemOperand(init_map, Map::kInstanceSizesOffset));
-      __ Ubfx(inobject_props, inst_sizes_or_attrs,
-              Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte);
+      __ Ubfx(
+          inobject_props, inst_sizes_or_attrs,
+          Map::kInObjectPropertiesOrConstructorFunctionIndexByte * kBitsPerByte,
+          kBitsPerByte);
       __ Sub(prealloc_fields, inobject_props, unused_props);
 
       // Calculate number of property fields in the object.
       __ Sub(prealloc_fields, inobject_props, unused_props);
 
       // Calculate number of property fields in the object.
index 36d322bb354dc7c790ba87f5fffbbecfd8204525..bca9b98d4d991e00926aea30598011098a3a0a11 100644 (file)
@@ -533,7 +533,7 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
     int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
     Handle<Map> object_function_map =
         factory->NewMap(JS_OBJECT_TYPE, instance_size);
     int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
     Handle<Map> object_function_map =
         factory->NewMap(JS_OBJECT_TYPE, instance_size);
-    object_function_map->set_inobject_properties(unused);
+    object_function_map->SetInObjectProperties(unused);
     JSFunction::SetInitialMap(object_fun, object_function_map,
                               isolate->factory()->null_value());
     object_function_map->set_unused_property_fields(unused);
     JSFunction::SetInitialMap(object_fun, object_function_map,
                               isolate->factory()->null_value());
     object_function_map->set_unused_property_fields(unused);
@@ -1172,7 +1172,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
     DCHECK(regexp_fun->has_initial_map());
     Handle<Map> initial_map(regexp_fun->initial_map());
 
     DCHECK(regexp_fun->has_initial_map());
     Handle<Map> initial_map(regexp_fun->initial_map());
 
-    DCHECK_EQ(0, initial_map->inobject_properties());
+    DCHECK_EQ(0, initial_map->GetInObjectProperties());
 
     PropertyAttributes final =
         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
 
     PropertyAttributes final =
         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
@@ -1217,7 +1217,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
     }
 
     static const int num_fields = JSRegExp::kInObjectFieldCount;
     }
 
     static const int num_fields = JSRegExp::kInObjectFieldCount;
-    initial_map->set_inobject_properties(num_fields);
+    initial_map->SetInObjectProperties(num_fields);
     initial_map->set_unused_property_fields(0);
     initial_map->set_instance_size(initial_map->instance_size() +
                                    num_fields * kPointerSize);
     initial_map->set_unused_property_fields(0);
     initial_map->set_instance_size(initial_map->instance_size() +
                                    num_fields * kPointerSize);
@@ -1313,7 +1313,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
     DCHECK_EQ(JSGeneratorObject::kResultSize,
               iterator_result_map->instance_size());
     DCHECK_EQ(JSGeneratorObject::kResultPropertyCount,
     DCHECK_EQ(JSGeneratorObject::kResultSize,
               iterator_result_map->instance_size());
     DCHECK_EQ(JSGeneratorObject::kResultPropertyCount,
-              iterator_result_map->inobject_properties());
+              iterator_result_map->GetInObjectProperties());
     Map::EnsureDescriptorSlack(iterator_result_map,
                                JSGeneratorObject::kResultPropertyCount);
 
     Map::EnsureDescriptorSlack(iterator_result_map,
                                JSGeneratorObject::kResultPropertyCount);
 
@@ -1368,15 +1368,15 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
     // @@iterator method is added later.
 
     map->set_function_with_prototype(true);
     // @@iterator method is added later.
 
     map->set_function_with_prototype(true);
-    map->set_inobject_properties(2);
+    map->SetInObjectProperties(2);
     native_context()->set_sloppy_arguments_map(*map);
 
     DCHECK(!function->has_initial_map());
     JSFunction::SetInitialMap(function, map,
                               isolate->initial_object_prototype());
 
     native_context()->set_sloppy_arguments_map(*map);
 
     DCHECK(!function->has_initial_map());
     JSFunction::SetInitialMap(function, map,
                               isolate->initial_object_prototype());
 
-    DCHECK(map->inobject_properties() > Heap::kArgumentsCalleeIndex);
-    DCHECK(map->inobject_properties() > Heap::kArgumentsLengthIndex);
+    DCHECK(map->GetInObjectProperties() > Heap::kArgumentsCalleeIndex);
+    DCHECK(map->GetInObjectProperties() > Heap::kArgumentsLengthIndex);
     DCHECK(!map->is_dictionary_map());
     DCHECK(IsFastObjectElementsKind(map->elements_kind()));
   }
     DCHECK(!map->is_dictionary_map());
     DCHECK(IsFastObjectElementsKind(map->elements_kind()));
   }
@@ -1385,12 +1385,12 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
     Handle<Map> map = isolate->sloppy_arguments_map();
     map = Map::Copy(map, "FastAliasedArguments");
     map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS);
     Handle<Map> map = isolate->sloppy_arguments_map();
     map = Map::Copy(map, "FastAliasedArguments");
     map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS);
-    DCHECK_EQ(2, map->inobject_properties());
+    DCHECK_EQ(2, map->GetInObjectProperties());
     native_context()->set_fast_aliased_arguments_map(*map);
 
     map = Map::Copy(map, "SlowAliasedArguments");
     map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
     native_context()->set_fast_aliased_arguments_map(*map);
 
     map = Map::Copy(map, "SlowAliasedArguments");
     map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
-    DCHECK_EQ(2, map->inobject_properties());
+    DCHECK_EQ(2, map->GetInObjectProperties());
     native_context()->set_slow_aliased_arguments_map(*map);
   }
 
     native_context()->set_slow_aliased_arguments_map(*map);
   }
 
@@ -1437,7 +1437,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
     DCHECK_EQ(native_context()->object_function()->prototype(),
               *isolate->initial_object_prototype());
     Map::SetPrototype(map, isolate->initial_object_prototype());
     DCHECK_EQ(native_context()->object_function()->prototype(),
               *isolate->initial_object_prototype());
     Map::SetPrototype(map, isolate->initial_object_prototype());
-    map->set_inobject_properties(1);
+    map->SetInObjectProperties(1);
 
     // Copy constructor from the sloppy arguments boilerplate.
     map->SetConstructor(
 
     // Copy constructor from the sloppy arguments boilerplate.
     map->SetConstructor(
@@ -1445,7 +1445,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
 
     native_context()->set_strict_arguments_map(*map);
 
 
     native_context()->set_strict_arguments_map(*map);
 
-    DCHECK(map->inobject_properties() > Heap::kArgumentsLengthIndex);
+    DCHECK(map->GetInObjectProperties() > Heap::kArgumentsLengthIndex);
     DCHECK(!map->is_dictionary_map());
     DCHECK(IsFastObjectElementsKind(map->elements_kind()));
   }
     DCHECK(!map->is_dictionary_map());
     DCHECK(IsFastObjectElementsKind(map->elements_kind()));
   }
@@ -2496,7 +2496,7 @@ bool Genesis::InstallNatives(ContextType context_type) {
       initial_map->AppendDescriptor(&input_field);
     }
 
       initial_map->AppendDescriptor(&input_field);
     }
 
-    initial_map->set_inobject_properties(2);
+    initial_map->SetInObjectProperties(2);
     initial_map->set_unused_property_fields(0);
 
     native_context()->set_regexp_result_map(*initial_map);
     initial_map->set_unused_property_fields(0);
 
     native_context()->set_regexp_result_map(*initial_map);
index e5bdc298f51e5ddcc9dd06263d72b25f1562e33d..11afad45693cee917a62724c8819fc1e3e4ad0ef 100644 (file)
@@ -1601,7 +1601,7 @@ Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) {
   // Make sure we don't have a ton of pre-allocated slots in the
   // global objects. They will be unused once we normalize the object.
   DCHECK(map->unused_property_fields() == 0);
   // Make sure we don't have a ton of pre-allocated slots in the
   // global objects. They will be unused once we normalize the object.
   DCHECK(map->unused_property_fields() == 0);
-  DCHECK(map->inobject_properties() == 0);
+  DCHECK(map->GetInObjectProperties() == 0);
 
   // Initial size of the backing store to avoid resize of the storage during
   // bootstrapping. The size differs between the JS global object ad the
 
   // Initial size of the backing store to avoid resize of the storage during
   // bootstrapping. The size differs between the JS global object ad the
index c151ab1072463317d5f4b56445077a01a9038a5e..042e4fbdd2316d1c3dcaa5ed27ccae550af615d5 100644 (file)
@@ -16,7 +16,7 @@ inline FieldIndex FieldIndex::ForInObjectOffset(int offset, Map* map) {
   int index = offset / kPointerSize;
   DCHECK(map == NULL ||
          index < (map->GetInObjectPropertyOffset(0) / kPointerSize +
   int index = offset / kPointerSize;
   DCHECK(map == NULL ||
          index < (map->GetInObjectPropertyOffset(0) / kPointerSize +
-                  map->inobject_properties()));
+                  map->GetInObjectProperties()));
   return FieldIndex(true, index, false, 0, 0, true);
 }
 
   return FieldIndex(true, index, false, 0, 0, true);
 }
 
@@ -25,7 +25,7 @@ inline FieldIndex FieldIndex::ForPropertyIndex(Map* map,
                                                int property_index,
                                                bool is_double) {
   DCHECK(map->instance_type() >= FIRST_NONSTRING_TYPE);
                                                int property_index,
                                                bool is_double) {
   DCHECK(map->instance_type() >= FIRST_NONSTRING_TYPE);
-  int inobject_properties = map->inobject_properties();
+  int inobject_properties = map->GetInObjectProperties();
   bool is_inobject = property_index < inobject_properties;
   int first_inobject_offset;
   if (is_inobject) {
   bool is_inobject = property_index < inobject_properties;
   int first_inobject_offset;
   if (is_inobject) {
@@ -58,7 +58,7 @@ inline FieldIndex FieldIndex::ForLoadByFieldIndex(Map* map, int orig_index) {
     field_index += JSObject::kHeaderSize / kPointerSize;
   }
   FieldIndex result(is_inobject, field_index, is_double,
     field_index += JSObject::kHeaderSize / kPointerSize;
   }
   FieldIndex result(is_inobject, field_index, is_double,
-                    map->inobject_properties(), first_inobject_offset);
+                    map->GetInObjectProperties(), first_inobject_offset);
   DCHECK(result.GetLoadByFieldIndex() == orig_index);
   return result;
 }
   DCHECK(result.GetLoadByFieldIndex() == orig_index);
   return result;
 }
index d8b72bed5330c8899c3124a6ea523edb56ccf7f4..5597553b733e4524bf2329c53487c190cbf53ca6 100644 (file)
@@ -2654,7 +2654,8 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
         ->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
   }
   reinterpret_cast<Map*>(result)->clear_unused();
         ->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
   }
   reinterpret_cast<Map*>(result)->clear_unused();
-  reinterpret_cast<Map*>(result)->set_inobject_properties(0);
+  reinterpret_cast<Map*>(result)
+      ->set_inobject_properties_or_constructor_function_index(0);
   reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
   reinterpret_cast<Map*>(result)->set_bit_field(0);
   reinterpret_cast<Map*>(result)->set_bit_field2(0);
   reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
   reinterpret_cast<Map*>(result)->set_bit_field(0);
   reinterpret_cast<Map*>(result)->set_bit_field2(0);
@@ -2681,7 +2682,7 @@ AllocationResult Heap::AllocateMap(InstanceType instance_type,
   map->set_constructor_or_backpointer(null_value(), SKIP_WRITE_BARRIER);
   map->set_instance_size(instance_size);
   map->clear_unused();
   map->set_constructor_or_backpointer(null_value(), SKIP_WRITE_BARRIER);
   map->set_instance_size(instance_size);
   map->clear_unused();
-  map->set_inobject_properties(0);
+  map->set_inobject_properties_or_constructor_function_index(0);
   map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
   map->set_dependent_code(DependentCode::cast(empty_fixed_array()),
                           SKIP_WRITE_BARRIER);
   map->set_code_cache(empty_fixed_array(), SKIP_WRITE_BARRIER);
   map->set_dependent_code(DependentCode::cast(empty_fixed_array()),
                           SKIP_WRITE_BARRIER);
@@ -2870,22 +2871,34 @@ bool Heap::CreateInitialMaps() {
 #define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \
   ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name)
 
 #define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \
   ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name)
 
+#define ALLOCATE_PRIMITIVE_MAP(instance_type, size, field_name, \
+                               constructor_function_index)      \
+  {                                                             \
+    ALLOCATE_MAP((instance_type), (size), field_name);          \
+    field_name##_map()->SetConstructorFunctionIndex(            \
+        (constructor_function_index));                          \
+  }
+
     ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, fixed_cow_array)
     DCHECK(fixed_array_map() != fixed_cow_array_map());
 
     ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info)
     ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, fixed_cow_array)
     DCHECK(fixed_array_map() != fixed_cow_array_map());
 
     ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info)
-    ALLOCATE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number)
+    ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
+                           Context::NUMBER_FUNCTION_INDEX)
     ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
                  mutable_heap_number)
     ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
                  mutable_heap_number)
-    ALLOCATE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol)
+    ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol,
+                           Context::SYMBOL_FUNCTION_INDEX)
 #define ALLOCATE_SIMD128_MAP(TYPE, Type, type, lane_count, lane_type) \
 #define ALLOCATE_SIMD128_MAP(TYPE, Type, type, lane_count, lane_type) \
-  ALLOCATE_MAP(SIMD128_VALUE_TYPE, Type::kSize, type)
+  ALLOCATE_PRIMITIVE_MAP(SIMD128_VALUE_TYPE, Type::kSize, type,       \
+                         Context::TYPE##_FUNCTION_INDEX)
     SIMD128_TYPES(ALLOCATE_SIMD128_MAP)
 #undef ALLOCATE_SIMD128_MAP
     ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign)
 
     ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole);
     SIMD128_TYPES(ALLOCATE_SIMD128_MAP)
 #undef ALLOCATE_SIMD128_MAP
     ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign)
 
     ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole);
-    ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean);
+    ALLOCATE_PRIMITIVE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean,
+                           Context::BOOLEAN_FUNCTION_INDEX);
     ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized);
     ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker);
     ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, no_interceptor_result_sentinel);
     ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized);
     ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker);
     ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, no_interceptor_result_sentinel);
@@ -2898,9 +2911,10 @@ bool Heap::CreateInitialMaps() {
         AllocationResult allocation = AllocateMap(entry.type, entry.size);
         if (!allocation.To(&obj)) return false;
       }
         AllocationResult allocation = AllocateMap(entry.type, entry.size);
         if (!allocation.To(&obj)) return false;
       }
+      Map* map = Map::cast(obj);
+      map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
       // Mark cons string maps as unstable, because their objects can change
       // maps during GC.
       // Mark cons string maps as unstable, because their objects can change
       // maps during GC.
-      Map* map = Map::cast(obj);
       if (StringShape(entry.type).IsCons()) map->mark_unstable();
       roots_[entry.index] = map;
     }
       if (StringShape(entry.type).IsCons()) map->mark_unstable();
       roots_[entry.index] = map;
     }
@@ -2909,7 +2923,9 @@ bool Heap::CreateInitialMaps() {
       AllocationResult allocation = AllocateMap(EXTERNAL_ONE_BYTE_STRING_TYPE,
                                                 ExternalOneByteString::kSize);
       if (!allocation.To(&obj)) return false;
       AllocationResult allocation = AllocateMap(EXTERNAL_ONE_BYTE_STRING_TYPE,
                                                 ExternalOneByteString::kSize);
       if (!allocation.To(&obj)) return false;
-      set_native_source_string_map(Map::cast(obj));
+      Map* map = Map::cast(obj);
+      map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX);
+      set_native_source_string_map(map);
     }
 
     ALLOCATE_VARSIZE_MAP(FIXED_DOUBLE_ARRAY_TYPE, fixed_double_array)
     }
 
     ALLOCATE_VARSIZE_MAP(FIXED_DOUBLE_ARRAY_TYPE, fixed_double_array)
@@ -2963,6 +2979,7 @@ bool Heap::CreateInitialMaps() {
     ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kSize, message_object)
     ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, external)
     external_map()->set_is_extensible(false);
     ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kSize, message_object)
     ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, external)
     external_map()->set_is_extensible(false);
+#undef ALLOCATE_PRIMITIVE_MAP
 #undef ALLOCATE_VARSIZE_MAP
 #undef ALLOCATE_MAP
   }
 #undef ALLOCATE_VARSIZE_MAP
 #undef ALLOCATE_MAP
   }
index 4838efb919cd3621b53ecc3f8bf64f5930acd985..4c3235e7b3c4082b55bc6bbb3212a77691e71ee0 100644 (file)
@@ -497,7 +497,7 @@ template <typename StaticVisitor>
 void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(Map* map,
                                                         HeapObject* object) {
   int last_property_offset =
 void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(Map* map,
                                                         HeapObject* object) {
   int last_property_offset =
-      JSRegExp::kSize + kPointerSize * map->inobject_properties();
+      JSRegExp::kSize + kPointerSize * map->GetInObjectProperties();
   StaticVisitor::VisitPointers(
       map->GetHeap(), object,
       HeapObject::RawField(object, JSRegExp::kPropertiesOffset),
   StaticVisitor::VisitPointers(
       map->GetHeap(), object,
       HeapObject::RawField(object, JSRegExp::kPropertiesOffset),
index 1819b32d0d3e8e7b31ee0887ca6f8bf02c56b5ee..807a65102940649f0cd132a30b2cef254810323f 100644 (file)
@@ -6106,10 +6106,10 @@ class HObjectAccess final {
                          Representation::Integer32());
   }
 
                          Representation::Integer32());
   }
 
-  static HObjectAccess ForMapInObjectProperties() {
-    return HObjectAccess(kInobject,
-                         Map::kInObjectPropertiesOffset,
-                         Representation::UInteger8());
+  static HObjectAccess ForMapInObjectPropertiesOrConstructorFunctionIndex() {
+    return HObjectAccess(
+        kInobject, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset,
+        Representation::UInteger8());
   }
 
   static HObjectAccess ForMapInstanceType() {
   }
 
   static HObjectAccess ForMapInstanceType() {
index 34d8c3d3fbac923dee3afc963138b81edad040e0..504c8b8ef92181c3b0057f1fae40f4346e2af9a4 100644 (file)
@@ -2047,14 +2047,8 @@ HValue* HGraphBuilder::BuildToObject(HValue* receiver) {
   receiver_is_smi.If<HIsSmiAndBranch>(receiver);
   receiver_is_smi.Then();
   {
   receiver_is_smi.If<HIsSmiAndBranch>(receiver);
   receiver_is_smi.Then();
   {
-    // Load native context.
-    HValue* native_context = BuildGetNativeContext();
-
-    // Load global Number function.
-    HValue* constructor = Add<HLoadNamedField>(
-        native_context, nullptr,
-        HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX));
-    Push(constructor);
+    // Use global Number function.
+    Push(Add<HConstant>(Context::NUMBER_FUNCTION_INDEX));
   }
   receiver_is_smi.Else();
   {
   }
   receiver_is_smi.Else();
   {
@@ -2071,75 +2065,23 @@ HValue* HGraphBuilder::BuildToObject(HValue* receiver) {
         Token::LT);
     receiver_is_not_spec_object.Then();
     {
         Token::LT);
     receiver_is_not_spec_object.Then();
     {
-      // Load native context.
-      HValue* native_context = BuildGetNativeContext();
-
-      IfBuilder receiver_is_heap_number(this);
-      receiver_is_heap_number.If<HCompareNumericAndBranch>(
-          receiver_instance_type, Add<HConstant>(HEAP_NUMBER_TYPE), Token::EQ);
-      receiver_is_heap_number.Then();
-      {
-        // Load global Number function.
-        HValue* constructor = Add<HLoadNamedField>(
-            native_context, nullptr,
-            HObjectAccess::ForContextSlot(Context::NUMBER_FUNCTION_INDEX));
-        Push(constructor);
-      }
-      receiver_is_heap_number.Else();
-      {
-        // Load boolean map (we cannot decide based on instance type, because
-        // it's ODDBALL_TYPE, which would also include null and undefined).
-        HValue* boolean_map = Add<HLoadRoot>(Heap::kBooleanMapRootIndex);
-
-        IfBuilder receiver_is_boolean(this);
-        receiver_is_boolean.If<HCompareObjectEqAndBranch>(receiver_map,
-                                                          boolean_map);
-        receiver_is_boolean.Then();
-        {
-          // Load global Boolean function.
-          HValue* constructor = Add<HLoadNamedField>(
-              native_context, nullptr,
-              HObjectAccess::ForContextSlot(Context::BOOLEAN_FUNCTION_INDEX));
-          Push(constructor);
-        }
-        receiver_is_boolean.Else();
-        {
-          IfBuilder receiver_is_string(this);
-          receiver_is_string.If<HCompareNumericAndBranch>(
-              receiver_instance_type, Add<HConstant>(FIRST_NONSTRING_TYPE),
-              Token::LT);
-          receiver_is_string.Then();
-          {
-            // Load global String function.
-            HValue* constructor = Add<HLoadNamedField>(
-                native_context, nullptr,
-                HObjectAccess::ForContextSlot(Context::STRING_FUNCTION_INDEX));
-            Push(constructor);
-          }
-          receiver_is_string.Else();
-          {
-            IfBuilder receiver_is_symbol(this);
-            receiver_is_symbol.If<HCompareNumericAndBranch>(
-                receiver_instance_type, Add<HConstant>(SYMBOL_TYPE), Token::EQ);
-            receiver_is_symbol.Then();
-            {
-              // Load global Symbol function.
-              HValue* constructor = Add<HLoadNamedField>(
-                  native_context, nullptr, HObjectAccess::ForContextSlot(
-                                               Context::SYMBOL_FUNCTION_INDEX));
-              Push(constructor);
-            }
-            // TODO(bmeurer): Don't inline this into crankshaft code, as it will
-            // deoptimize on all SIMD128 objects.
-            receiver_is_symbol.ElseDeopt(
-                Deoptimizer::kUndefinedOrNullInToObject);
-            receiver_is_symbol.JoinContinuation(&wrap);
-          }
-          receiver_is_string.JoinContinuation(&wrap);
-        }
-        receiver_is_boolean.JoinContinuation(&wrap);
-      }
-      receiver_is_heap_number.JoinContinuation(&wrap);
+      // Load the constructor function index from the {receiver} map.
+      HValue* constructor_function_index = Add<HLoadNamedField>(
+          receiver_map, nullptr,
+          HObjectAccess::ForMapInObjectPropertiesOrConstructorFunctionIndex());
+
+      // Check if {receiver} has a constructor (null and undefined have no
+      // constructors, so we deoptimize to the runtime to throw an exception).
+      IfBuilder constructor_function_index_is_invalid(this);
+      constructor_function_index_is_invalid.If<HCompareNumericAndBranch>(
+          constructor_function_index,
+          Add<HConstant>(Map::kNoConstructorFunctionIndex), Token::EQ);
+      constructor_function_index_is_invalid.ThenDeopt(
+          Deoptimizer::kUndefinedOrNullInToObject);
+      constructor_function_index_is_invalid.End();
+
+      // Use the global constructor function.
+      Push(constructor_function_index);
     }
     receiver_is_not_spec_object.JoinContinuation(&wrap);
   }
     }
     receiver_is_not_spec_object.JoinContinuation(&wrap);
   }
@@ -2149,8 +2091,15 @@ HValue* HGraphBuilder::BuildToObject(HValue* receiver) {
   IfBuilder if_wrap(this, &wrap);
   if_wrap.Then();
   {
   IfBuilder if_wrap(this, &wrap);
   if_wrap.Then();
   {
+    // Grab the constructor function index.
+    HValue* constructor_index = Pop();
+
+    // Load native context.
+    HValue* native_context = BuildGetNativeContext();
+
     // Determine the initial map for the global constructor.
     // Determine the initial map for the global constructor.
-    HValue* constructor = Pop();
+    HValue* constructor = Add<HLoadKeyed>(native_context, constructor_index,
+                                          nullptr, FAST_ELEMENTS);
     HValue* constructor_initial_map = Add<HLoadNamedField>(
         constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap());
     // Allocate and initialize a JSValue wrapper.
     HValue* constructor_initial_map = Add<HLoadNamedField>(
         constructor, nullptr, HObjectAccess::ForPrototypeOrInitialMap());
     // Allocate and initialize a JSValue wrapper.
@@ -6443,7 +6392,7 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
     int descriptor = transition()->LastAdded();
     int index =
         transition()->instance_descriptors()->GetFieldIndex(descriptor) -
     int descriptor = transition()->LastAdded();
     int index =
         transition()->instance_descriptors()->GetFieldIndex(descriptor) -
-        map_->inobject_properties();
+        map_->GetInObjectProperties();
     PropertyDetails details =
         transition()->instance_descriptors()->GetDetails(descriptor);
     Representation representation = details.representation();
     PropertyDetails details =
         transition()->instance_descriptors()->GetDetails(descriptor);
     Representation representation = details.representation();
@@ -9963,9 +9912,9 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
 
 void HOptimizedGraphBuilder::BuildInitializeInobjectProperties(
     HValue* receiver, Handle<Map> initial_map) {
 
 void HOptimizedGraphBuilder::BuildInitializeInobjectProperties(
     HValue* receiver, Handle<Map> initial_map) {
-  if (initial_map->inobject_properties() != 0) {
+  if (initial_map->GetInObjectProperties() != 0) {
     HConstant* undefined = graph()->GetConstantUndefined();
     HConstant* undefined = graph()->GetConstantUndefined();
-    for (int i = 0; i < initial_map->inobject_properties(); i++) {
+    for (int i = 0; i < initial_map->GetInObjectProperties(); i++) {
       int property_offset = initial_map->GetInObjectPropertyOffset(i);
       Add<HStoreNamedField>(receiver, HObjectAccess::ForMapAndOffset(
                                           initial_map, property_offset),
       int property_offset = initial_map->GetInObjectPropertyOffset(i);
       Add<HStoreNamedField>(receiver, HObjectAccess::ForMapAndOffset(
                                           initial_map, property_offset),
@@ -11778,7 +11727,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
     }
   }
 
     }
   }
 
-  int inobject_properties = boilerplate_object->map()->inobject_properties();
+  int inobject_properties = boilerplate_object->map()->GetInObjectProperties();
   HInstruction* value_instruction =
       Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
   for (int i = copied_fields; i < inobject_properties; i++) {
   HInstruction* value_instruction =
       Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
   for (int i = copied_fields; i < inobject_properties; i++) {
index bfb67aaedf5d24df2e6b114120faf96a52678fa3..92576a3160fc86afb054a8b8fd266dc901d74613 100644 (file)
@@ -2637,7 +2637,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
              lookup_type_ == TRANSITION_TYPE);
       DCHECK(number_ < map->NumberOfOwnDescriptors());
       int field_index = map->instance_descriptors()->GetFieldIndex(number_);
              lookup_type_ == TRANSITION_TYPE);
       DCHECK(number_ < map->NumberOfOwnDescriptors());
       int field_index = map->instance_descriptors()->GetFieldIndex(number_);
-      return field_index - map->inobject_properties();
+      return field_index - map->GetInObjectProperties();
     }
 
     void LookupDescriptor(Map* map, Name* name) {
     }
 
     void LookupDescriptor(Map* map, Name* name) {
index d4cbf9486b566b0c3f9d25429f5d411b6cd0fdfd..bbde80cde90179762e7c5beedc48b8c08516edb4 100644 (file)
@@ -224,7 +224,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ j(less, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
         __ j(less, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
-        __ movzx_b(esi, FieldOperand(eax, Map::kInObjectPropertiesOffset));
+        __ movzx_b(
+            esi,
+            FieldOperand(
+                eax, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset));
         __ movzx_b(eax, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));
         __ sub(esi, eax);
         __ lea(esi,
         __ movzx_b(eax, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));
         __ sub(esi, eax);
         __ lea(esi,
index 74844d869bbced3747c3e2b27aeb821383827083..594fe194f5d8320a9e3d08293c9aa1e8b8e2c591 100644 (file)
@@ -99,28 +99,11 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
                                                   Handle<Name> name,
                                                   Label* miss,
                                                   ReturnHolder return_what) {
                                                   Handle<Name> name,
                                                   Label* miss,
                                                   ReturnHolder return_what) {
-  PrototypeCheckType check_type = CHECK_ALL_MAPS;
-  int function_index = -1;
-  if (map()->instance_type() < FIRST_NONSTRING_TYPE) {
-    function_index = Context::STRING_FUNCTION_INDEX;
-  } else if (map()->instance_type() == SYMBOL_TYPE) {
-    function_index = Context::SYMBOL_FUNCTION_INDEX;
-  } else if (map()->instance_type() == HEAP_NUMBER_TYPE) {
-    function_index = Context::NUMBER_FUNCTION_INDEX;
-  } else if (*map() == isolate()->heap()->boolean_map()) {
-    function_index = Context::BOOLEAN_FUNCTION_INDEX;
-// clang-format off
-#define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type)           \
-  } else if (map().is_identical_to(isolate()->factory()->type##_map())) { \
-    function_index = Context::TYPE##_FUNCTION_INDEX;
-  SIMD128_TYPES(SIMD128_TYPE)
-#undef SIMD128_TYPE
-    // clang-format on
-  } else {
-    check_type = SKIP_RECEIVER;
-  }
-
-  if (check_type == CHECK_ALL_MAPS) {
+  PrototypeCheckType check_type = SKIP_RECEIVER;
+  int function_index = map()->IsPrimitiveMap()
+                           ? map()->GetConstructorFunctionIndex()
+                           : Map::kNoConstructorFunctionIndex;
+  if (function_index != Map::kNoConstructorFunctionIndex) {
     GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index,
                                               scratch1(), miss);
     Object* function = isolate()->native_context()->get(function_index);
     GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index,
                                               scratch1(), miss);
     Object* function = isolate()->native_context()->get(function_index);
@@ -128,6 +111,7 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
     Handle<Map> map(JSObject::cast(prototype)->map());
     set_map(map);
     object_reg = scratch1();
     Handle<Map> map(JSObject::cast(prototype)->map());
     set_map(map);
     object_reg = scratch1();
+    check_type = CHECK_ALL_MAPS;
   }
 
   // Check that the maps starting from the prototype haven't changed.
   }
 
   // Check that the maps starting from the prototype haven't changed.
index d6802b67d0903a0ccd4f4cc2253b6d86ae9bf9b6..bce3c1206d32e1441c1f155356353ce271795b88 100644 (file)
@@ -127,25 +127,14 @@ void IC::UpdateTarget() { target_ = handle(raw_target(), isolate_); }
 
 
 JSFunction* IC::GetRootConstructor(Map* receiver_map, Context* native_context) {
 
 
 JSFunction* IC::GetRootConstructor(Map* receiver_map, Context* native_context) {
-  Isolate* isolate = receiver_map->GetIsolate();
-  if (receiver_map == isolate->heap()->boolean_map()) {
-    return native_context->boolean_function();
+  DisallowHeapAllocation no_alloc;
+  if (receiver_map->IsPrimitiveMap()) {
+    int constructor_function_index =
+        receiver_map->GetConstructorFunctionIndex();
+    if (constructor_function_index != Map::kNoConstructorFunctionIndex) {
+      return JSFunction::cast(native_context->get(constructor_function_index));
+    }
   }
   }
-  if (receiver_map->instance_type() == HEAP_NUMBER_TYPE) {
-    return native_context->number_function();
-  }
-  if (receiver_map->instance_type() < FIRST_NONSTRING_TYPE) {
-    return native_context->string_function();
-  }
-  if (receiver_map->instance_type() == SYMBOL_TYPE) {
-    return native_context->symbol_function();
-  }
-#define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \
-  if (receiver_map == isolate->heap()->type##_map()) {        \
-    return native_context->type##_function();                 \
-  }
-  SIMD128_TYPES(SIMD128_TYPE)
-#undef SIMD128_TYPE
   return nullptr;
 }
 
   return nullptr;
 }
 
index 77671328b4c1b745a55bbfea1f99d9bb9e0f05e4..cb3325b31f90ecc6e78e9af693e107712d06ede8 100644 (file)
@@ -161,7 +161,7 @@ int LayoutDescriptor::GetSlowModeBackingStoreLength(int length) {
 
 int LayoutDescriptor::CalculateCapacity(Map* map, DescriptorArray* descriptors,
                                         int num_descriptors) {
 
 int LayoutDescriptor::CalculateCapacity(Map* map, DescriptorArray* descriptors,
                                         int num_descriptors) {
-  int inobject_properties = map->inobject_properties();
+  int inobject_properties = map->GetInObjectProperties();
   if (inobject_properties == 0) return 0;
 
   DCHECK_LE(num_descriptors, descriptors->number_of_descriptors());
   if (inobject_properties == 0) return 0;
 
   DCHECK_LE(num_descriptors, descriptors->number_of_descriptors());
@@ -195,7 +195,7 @@ LayoutDescriptor* LayoutDescriptor::Initialize(
     LayoutDescriptor* layout_descriptor, Map* map, DescriptorArray* descriptors,
     int num_descriptors) {
   DisallowHeapAllocation no_allocation;
     LayoutDescriptor* layout_descriptor, Map* map, DescriptorArray* descriptors,
     int num_descriptors) {
   DisallowHeapAllocation no_allocation;
-  int inobject_properties = map->inobject_properties();
+  int inobject_properties = map->GetInObjectProperties();
 
   for (int i = 0; i < num_descriptors; i++) {
     PropertyDetails details = descriptors->GetDetails(i);
 
   for (int i = 0; i < num_descriptors; i++) {
     PropertyDetails details = descriptors->GetDetails(i);
@@ -214,7 +214,7 @@ LayoutDescriptor* LayoutDescriptor::Initialize(
 }
 
 
 }
 
 
-// InobjectPropertiesHelper is a helper class for querying whether inobject
+// LayoutDescriptorHelper is a helper class for querying whether inobject
 // property at offset is Double or not.
 LayoutDescriptorHelper::LayoutDescriptorHelper(Map* map)
     : all_fields_tagged_(true),
 // property at offset is Double or not.
 LayoutDescriptorHelper::LayoutDescriptorHelper(Map* map)
     : all_fields_tagged_(true),
@@ -227,7 +227,7 @@ LayoutDescriptorHelper::LayoutDescriptorHelper(Map* map)
     return;
   }
 
     return;
   }
 
-  int inobject_properties = map->inobject_properties();
+  int inobject_properties = map->GetInObjectProperties();
   DCHECK(inobject_properties > 0);
   header_size_ = map->instance_size() - (inobject_properties * kPointerSize);
   DCHECK(header_size_ >= 0);
   DCHECK(inobject_properties > 0);
   header_size_ = map->instance_size() - (inobject_properties * kPointerSize);
   DCHECK(header_size_ >= 0);
index 25cece822a374ce1efb17eeb5c6f5786b7292276..b961a7de96dd7b88a02be10b25b9230141bfff9f 100644 (file)
@@ -46,7 +46,7 @@ Handle<LayoutDescriptor> LayoutDescriptor::ShareAppend(
   Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(),
                                              isolate);
 
   Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(),
                                              isolate);
 
-  if (!InobjectUnboxedField(map->inobject_properties(), details)) {
+  if (!InobjectUnboxedField(map->GetInObjectProperties(), details)) {
     DCHECK(details.location() != kField ||
            layout_descriptor->IsTagged(details.field_index()));
     return layout_descriptor;
     DCHECK(details.location() != kField ||
            layout_descriptor->IsTagged(details.field_index()));
     return layout_descriptor;
@@ -73,7 +73,7 @@ Handle<LayoutDescriptor> LayoutDescriptor::AppendIfFastOrUseFull(
   if (layout_descriptor->IsSlowLayout()) {
     return full_layout_descriptor;
   }
   if (layout_descriptor->IsSlowLayout()) {
     return full_layout_descriptor;
   }
-  if (!InobjectUnboxedField(map->inobject_properties(), details)) {
+  if (!InobjectUnboxedField(map->GetInObjectProperties(), details)) {
     DCHECK(details.location() != kField ||
            layout_descriptor->IsTagged(details.field_index()));
     return handle(layout_descriptor, map->GetIsolate());
     DCHECK(details.location() != kField ||
            layout_descriptor->IsTagged(details.field_index()));
     return handle(layout_descriptor, map->GetIsolate());
index f4a47238d0319d7dbcfbffb51b969665b3cee60a..e27199a904f9adc655c7c3eace7b5f5e15293130 100644 (file)
@@ -440,7 +440,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
                   Operand(Map::kSlackTrackingCounterEnd));
 
         // Allocate object with a slack.
                   Operand(Map::kSlackTrackingCounterEnd));
 
         // Allocate object with a slack.
-        __ lbu(a0, FieldMemOperand(a2, Map::kInObjectPropertiesOffset));
+        __ lbu(
+            a0,
+            FieldMemOperand(
+                a2, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset));
         __ lbu(a2, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
         __ subu(a0, a0, a2);
         __ sll(at, a0, kPointerSizeLog2);
         __ lbu(a2, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
         __ subu(a0, a0, a2);
         __ sll(at, a0, kPointerSizeLog2);
index b60d1a8142814b9533f3bd979388355899f0a585..6d97e4405f1b0c343818a2a0faa0fca8de3f30f6 100644 (file)
@@ -439,7 +439,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
                   Operand(static_cast<int64_t>(Map::kSlackTrackingCounterEnd)));
 
         // Allocate object with a slack.
                   Operand(static_cast<int64_t>(Map::kSlackTrackingCounterEnd)));
 
         // Allocate object with a slack.
-        __ lbu(a0, FieldMemOperand(a2, Map::kInObjectPropertiesOffset));
+        __ lbu(
+            a0,
+            FieldMemOperand(
+                a2, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset));
         __ lbu(a2, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
         __ dsubu(a0, a0, a2);
         __ dsll(at, a0, kPointerSizeLog2);
         __ lbu(a2, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
         __ dsubu(a0, a0, a2);
         __ dsll(at, a0, kPointerSizeLog2);
index 5a80d2a04897e6a02b5d1d058a70b7fd4ac1d95b..c278bbc5d1738aa3b9b3c79ba42f2af7a962f2e6 100644 (file)
@@ -264,7 +264,7 @@ void JSObject::JSObjectVerify() {
   }
 
   if (HasFastProperties()) {
   }
 
   if (HasFastProperties()) {
-    int actual_unused_property_fields = map()->inobject_properties() +
+    int actual_unused_property_fields = map()->GetInObjectProperties() +
                                         properties()->length() -
                                         map()->NextFreePropertyIndex();
     if (map()->unused_property_fields() != actual_unused_property_fields) {
                                         properties()->length() -
                                         map()->NextFreePropertyIndex();
     if (map()->unused_property_fields() != actual_unused_property_fields) {
index 62269acc46d53c576ce13deff34ee77e6df8703c..27c969564d094cd326b620f9f55a751b00b78d38 100644 (file)
@@ -186,7 +186,9 @@ bool Object::IsString() const {
 
 
 bool Object::IsName() const {
 
 
 bool Object::IsName() const {
-  return IsString() || IsSymbol();
+  STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
+  return Object::IsHeapObject() &&
+         HeapObject::cast(this)->map()->instance_type() <= LAST_NAME_TYPE;
 }
 
 
 }
 
 
@@ -985,7 +987,7 @@ bool Object::IsOrderedHashMap() const {
 
 
 bool Object::IsPrimitive() const {
 
 
 bool Object::IsPrimitive() const {
-  return IsOddball() || IsNumber() || IsString();
+  return IsSmi() || HeapObject::cast(this)->map()->IsPrimitiveMap();
 }
 
 
 }
 
 
@@ -2117,7 +2119,7 @@ int JSObject::GetInternalFieldCount() {
   // Make sure to adjust for the number of in-object properties. These
   // properties do contribute to the size, but are not internal fields.
   return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
   // Make sure to adjust for the number of in-object properties. These
   // properties do contribute to the size, but are not internal fields.
   return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
-         map()->inobject_properties();
+         map()->GetInObjectProperties();
 }
 
 
 }
 
 
@@ -2274,7 +2276,7 @@ void JSObject::InitializeBody(Map* map,
   int offset = kHeaderSize;
   if (filler_value != pre_allocated_value) {
     int pre_allocated =
   int offset = kHeaderSize;
   if (filler_value != pre_allocated_value) {
     int pre_allocated =
-        map->inobject_properties() - map->unused_property_fields();
+        map->GetInObjectProperties() - map->unused_property_fields();
     DCHECK(pre_allocated * kPointerSize + kHeaderSize <= size);
     for (int i = 0; i < pre_allocated; i++) {
       WRITE_FIELD(this, offset, pre_allocated_value);
     DCHECK(pre_allocated * kPointerSize + kHeaderSize <= size);
     for (int i = 0; i < pre_allocated; i++) {
       WRITE_FIELD(this, offset, pre_allocated_value);
@@ -2298,8 +2300,8 @@ bool Map::TooManyFastProperties(StoreFromKeyed store_mode) {
   if (unused_property_fields() != 0) return false;
   if (is_prototype_map()) return false;
   int minimum = store_mode == CERTAINLY_NOT_STORE_FROM_KEYED ? 128 : 12;
   if (unused_property_fields() != 0) return false;
   if (is_prototype_map()) return false;
   int minimum = store_mode == CERTAINLY_NOT_STORE_FROM_KEYED ? 128 : 12;
-  int limit = Max(minimum, inobject_properties());
-  int external = NumberOfFields() - inobject_properties();
+  int limit = Max(minimum, GetInObjectProperties());
+  int external = NumberOfFields() - GetInObjectProperties();
   return external > limit;
 }
 
   return external > limit;
 }
 
@@ -3986,14 +3988,46 @@ int Map::instance_size() {
 }
 
 
 }
 
 
-int Map::inobject_properties() {
-  return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
+int Map::inobject_properties_or_constructor_function_index() {
+  return READ_BYTE_FIELD(this,
+                         kInObjectPropertiesOrConstructorFunctionIndexOffset);
+}
+
+
+void Map::set_inobject_properties_or_constructor_function_index(int value) {
+  DCHECK(0 <= value && value < 256);
+  WRITE_BYTE_FIELD(this, kInObjectPropertiesOrConstructorFunctionIndexOffset,
+                   static_cast<byte>(value));
+}
+
+
+int Map::GetInObjectProperties() {
+  DCHECK(IsJSObjectMap());
+  return inobject_properties_or_constructor_function_index();
+}
+
+
+void Map::SetInObjectProperties(int value) {
+  DCHECK(IsJSObjectMap());
+  set_inobject_properties_or_constructor_function_index(value);
+}
+
+
+int Map::GetConstructorFunctionIndex() {
+  DCHECK(IsPrimitiveMap());
+  return inobject_properties_or_constructor_function_index();
+}
+
+
+void Map::SetConstructorFunctionIndex(int value) {
+  DCHECK(IsPrimitiveMap());
+  set_inobject_properties_or_constructor_function_index(value);
 }
 
 
 int Map::GetInObjectPropertyOffset(int index) {
   // Adjust for the number of properties stored in the object.
 }
 
 
 int Map::GetInObjectPropertyOffset(int index) {
   // Adjust for the number of properties stored in the object.
-  index -= inobject_properties();
+  index -= GetInObjectProperties();
   DCHECK(index <= 0);
   return instance_size() + (index * kPointerSize);
 }
   DCHECK(index <= 0);
   return instance_size() + (index * kPointerSize);
 }
@@ -4061,12 +4095,6 @@ void Map::set_instance_size(int value) {
 }
 
 
 }
 
 
-void Map::set_inobject_properties(int value) {
-  DCHECK(0 <= value && value < 256);
-  WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
-}
-
-
 void Map::clear_unused() { WRITE_BYTE_FIELD(this, kUnusedOffset, 0); }
 
 
 void Map::clear_unused() { WRITE_BYTE_FIELD(this, kUnusedOffset, 0); }
 
 
index 54518a21ff619506889e45c32370329cf19a9053..1f72ce3c880d9bb411d92f1584c93530bb70f222 100644 (file)
@@ -465,7 +465,9 @@ void Map::MapPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "Map");
   os << " - type: " << TypeToString(instance_type()) << "\n";
   os << " - instance size: " << instance_size() << "\n";
   HeapObject::PrintHeader(os, "Map");
   os << " - type: " << TypeToString(instance_type()) << "\n";
   os << " - instance size: " << instance_size() << "\n";
-  os << " - inobject properties: " << inobject_properties() << "\n";
+  if (IsJSObjectMap()) {
+    os << " - inobject properties: " << GetInObjectProperties() << "\n";
+  }
   os << " - elements kind: " << ElementsKindToString(elements_kind()) << "\n";
   os << " - unused property fields: " << unused_property_fields() << "\n";
   if (is_deprecated()) os << " - deprecated_map\n";
   os << " - elements kind: " << ElementsKindToString(elements_kind()) << "\n";
   os << " - unused property fields: " << unused_property_fields() << "\n";
   if (is_deprecated()) os << " - deprecated_map\n";
index e45d0cda7a82d46dd4eb3cb924f31f6780a5f728..69f3965172259ca7f713d6e7ef65d81135e1449a 100644 (file)
@@ -72,34 +72,17 @@ MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
                                          Handle<Context> native_context) {
   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
   Handle<JSFunction> constructor;
                                          Handle<Context> native_context) {
   if (object->IsJSReceiver()) return Handle<JSReceiver>::cast(object);
   Handle<JSFunction> constructor;
-  if (object->IsNumber()) {
+  if (object->IsSmi()) {
     constructor = handle(native_context->number_function(), isolate);
     constructor = handle(native_context->number_function(), isolate);
-  } else if (object->IsBoolean()) {
-    constructor = handle(native_context->boolean_function(), isolate);
-  } else if (object->IsString()) {
-    constructor = handle(native_context->string_function(), isolate);
-  } else if (object->IsSymbol()) {
-    constructor = handle(native_context->symbol_function(), isolate);
-  } else if (object->IsSimd128Value()) {
-    if (object->IsFloat32x4()) {
-      constructor = handle(native_context->float32x4_function(), isolate);
-    } else if (object->IsInt32x4()) {
-      constructor = handle(native_context->int32x4_function(), isolate);
-    } else if (object->IsBool32x4()) {
-      constructor = handle(native_context->bool32x4_function(), isolate);
-    } else if (object->IsInt16x8()) {
-      constructor = handle(native_context->int16x8_function(), isolate);
-    } else if (object->IsBool16x8()) {
-      constructor = handle(native_context->bool16x8_function(), isolate);
-    } else if (object->IsInt8x16()) {
-      constructor = handle(native_context->int8x16_function(), isolate);
-    } else if (object->IsBool8x16()) {
-      constructor = handle(native_context->bool8x16_function(), isolate);
-    } else {
-      UNREACHABLE();
-    }
   } else {
   } else {
-    return MaybeHandle<JSReceiver>();
+    int constructor_function_index =
+        Handle<HeapObject>::cast(object)->map()->GetConstructorFunctionIndex();
+    if (constructor_function_index == Map::kNoConstructorFunctionIndex) {
+      return MaybeHandle<JSReceiver>();
+    }
+    constructor = handle(
+        JSFunction::cast(native_context->get(constructor_function_index)),
+        isolate);
   }
   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
   Handle<JSValue>::cast(result)->set_value(*object);
   }
   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
   Handle<JSValue>::cast(result)->set_value(*object);
@@ -618,49 +601,23 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
 Map* Object::GetRootMap(Isolate* isolate) {
   DisallowHeapAllocation no_alloc;
   if (IsSmi()) {
 Map* Object::GetRootMap(Isolate* isolate) {
   DisallowHeapAllocation no_alloc;
   if (IsSmi()) {
-    Context* context = isolate->context()->native_context();
-    return context->number_function()->initial_map();
+    Context* native_context = isolate->context()->native_context();
+    return native_context->number_function()->initial_map();
   }
 
   }
 
-  HeapObject* heap_object = HeapObject::cast(this);
-
   // The object is either a number, a string, a symbol, a boolean, a SIMD value,
   // a real JS object, or a Harmony proxy.
   // The object is either a number, a string, a symbol, a boolean, a SIMD value,
   // a real JS object, or a Harmony proxy.
+  HeapObject* heap_object = HeapObject::cast(this);
   if (heap_object->IsJSReceiver()) {
     return heap_object->map();
   }
   if (heap_object->IsJSReceiver()) {
     return heap_object->map();
   }
-  Context* context = isolate->context()->native_context();
-
-  if (heap_object->IsHeapNumber()) {
-    return context->number_function()->initial_map();
-  }
-  if (heap_object->IsString()) {
-    return context->string_function()->initial_map();
-  }
-  if (heap_object->IsSymbol()) {
-    return context->symbol_function()->initial_map();
-  }
-  if (heap_object->IsBoolean()) {
-    return context->boolean_function()->initial_map();
-  }
-  if (heap_object->IsSimd128Value()) {
-    if (heap_object->IsFloat32x4()) {
-      return context->float32x4_function()->initial_map();
-    } else if (heap_object->IsInt32x4()) {
-      return context->int32x4_function()->initial_map();
-    } else if (heap_object->IsBool32x4()) {
-      return context->bool32x4_function()->initial_map();
-    } else if (heap_object->IsInt16x8()) {
-      return context->int16x8_function()->initial_map();
-    } else if (heap_object->IsBool16x8()) {
-      return context->bool16x8_function()->initial_map();
-    } else if (heap_object->IsInt8x16()) {
-      return context->int8x16_function()->initial_map();
-    } else if (heap_object->IsBool8x16()) {
-      return context->bool8x16_function()->initial_map();
-    } else {
-      UNREACHABLE();
-    }
+  int constructor_function_index =
+      heap_object->map()->GetConstructorFunctionIndex();
+  if (constructor_function_index != Map::kNoConstructorFunctionIndex) {
+    Context* native_context = isolate->context()->native_context();
+    JSFunction* constructor_function =
+        JSFunction::cast(native_context->get(constructor_function_index));
+    return constructor_function->initial_map();
   }
   return isolate->heap()->null_value()->map();
 }
   }
   return isolate->heap()->null_value()->map();
 }
@@ -1731,11 +1688,11 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
 
   // If no fields were added, and no inobject properties were removed, setting
   // the map is sufficient.
 
   // If no fields were added, and no inobject properties were removed, setting
   // the map is sufficient.
-  if (target_inobject == inobject_properties()) return false;
+  if (target_inobject == GetInObjectProperties()) return false;
   // In-object slack tracking may have reduced the object size of the new map.
   // In that case, succeed if all existing fields were inobject, and they still
   // fit within the new inobject size.
   // In-object slack tracking may have reduced the object size of the new map.
   // In that case, succeed if all existing fields were inobject, and they still
   // fit within the new inobject size.
-  DCHECK(target_inobject < inobject_properties());
+  DCHECK(target_inobject < GetInObjectProperties());
   if (target_number_of_fields <= target_inobject) {
     DCHECK(target_number_of_fields + target_unused == target_inobject);
     return false;
   if (target_number_of_fields <= target_inobject) {
     DCHECK(target_number_of_fields + target_unused == target_inobject);
     return false;
@@ -1842,7 +1799,7 @@ void JSObject::MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
   Handle<Map> old_map(object->map());
   int old_number_of_fields;
   int number_of_fields = new_map->NumberOfFields();
   Handle<Map> old_map(object->map());
   int old_number_of_fields;
   int number_of_fields = new_map->NumberOfFields();
-  int inobject = new_map->inobject_properties();
+  int inobject = new_map->GetInObjectProperties();
   int unused = new_map->unused_property_fields();
 
   // Nothing to do if no functions were converted to fields and no smis were
   int unused = new_map->unused_property_fields();
 
   // Nothing to do if no functions were converted to fields and no smis were
@@ -4049,7 +4006,8 @@ MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy,
 
 
 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
 
 
 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
-  DCHECK(object->map()->inobject_properties() == map->inobject_properties());
+  DCHECK(object->map()->GetInObjectProperties() ==
+         map->GetInObjectProperties());
   ElementsKind obj_kind = object->map()->elements_kind();
   ElementsKind map_kind = map->elements_kind();
   if (map_kind != obj_kind) {
   ElementsKind obj_kind = object->map()->elements_kind();
   ElementsKind map_kind = map->elements_kind();
   if (map_kind != obj_kind) {
@@ -4561,7 +4519,7 @@ void JSObject::MigrateFastToSlow(Handle<JSObject> object,
 
   // Ensure that in-object space of slow-mode object does not contain random
   // garbage.
 
   // Ensure that in-object space of slow-mode object does not contain random
   // garbage.
-  int inobject_properties = new_map->inobject_properties();
+  int inobject_properties = new_map->GetInObjectProperties();
   for (int i = 0; i < inobject_properties; i++) {
     FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
     object->RawFastPropertyAtPut(index, Smi::FromInt(0));
   for (int i = 0; i < inobject_properties; i++) {
     FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
     object->RawFastPropertyAtPut(index, Smi::FromInt(0));
@@ -4618,7 +4576,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
 
   Handle<Map> old_map(object->map(), isolate);
 
 
   Handle<Map> old_map(object->map(), isolate);
 
-  int inobject_props = old_map->inobject_properties();
+  int inobject_props = old_map->GetInObjectProperties();
 
   // Allocate new map.
   Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
 
   // Allocate new map.
   Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
@@ -6506,13 +6464,13 @@ Handle<Map> Map::CopyNormalized(Handle<Map> map,
                                 PropertyNormalizationMode mode) {
   int new_instance_size = map->instance_size();
   if (mode == CLEAR_INOBJECT_PROPERTIES) {
                                 PropertyNormalizationMode mode) {
   int new_instance_size = map->instance_size();
   if (mode == CLEAR_INOBJECT_PROPERTIES) {
-    new_instance_size -= map->inobject_properties() * kPointerSize;
+    new_instance_size -= map->GetInObjectProperties() * kPointerSize;
   }
 
   Handle<Map> result = RawCopy(map, new_instance_size);
 
   if (mode != CLEAR_INOBJECT_PROPERTIES) {
   }
 
   Handle<Map> result = RawCopy(map, new_instance_size);
 
   if (mode != CLEAR_INOBJECT_PROPERTIES) {
-    result->set_inobject_properties(map->inobject_properties());
+    result->SetInObjectProperties(map->GetInObjectProperties());
   }
 
   result->set_dictionary_map(true);
   }
 
   result->set_dictionary_map(true);
@@ -6530,7 +6488,7 @@ Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) {
   Handle<Map> result = RawCopy(map, map->instance_size());
 
   // Please note instance_type and instance_size are set when allocated.
   Handle<Map> result = RawCopy(map, map->instance_size());
 
   // Please note instance_type and instance_size are set when allocated.
-  result->set_inobject_properties(map->inobject_properties());
+  result->SetInObjectProperties(map->GetInObjectProperties());
   result->set_unused_property_fields(map->unused_property_fields());
 
   result->ClearCodeCache(map->GetHeap());
   result->set_unused_property_fields(map->unused_property_fields());
 
   result->ClearCodeCache(map->GetHeap());
@@ -6842,7 +6800,7 @@ Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
       JSObject::kHeaderSize + kPointerSize * inobject_properties;
 
   // Adjust the map with the extra inobject properties.
       JSObject::kHeaderSize + kPointerSize * inobject_properties;
 
   // Adjust the map with the extra inobject properties.
-  copy->set_inobject_properties(inobject_properties);
+  copy->SetInObjectProperties(inobject_properties);
   copy->set_unused_property_fields(inobject_properties);
   copy->set_instance_size(new_instance_size);
   copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy));
   copy->set_unused_property_fields(inobject_properties);
   copy->set_instance_size(new_instance_size);
   copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy));
@@ -9236,10 +9194,10 @@ bool Map::EquivalentToForTransition(Map* other) {
 
 bool Map::EquivalentToForNormalization(Map* other,
                                        PropertyNormalizationMode mode) {
 
 bool Map::EquivalentToForNormalization(Map* other,
                                        PropertyNormalizationMode mode) {
-  int properties = mode == CLEAR_INOBJECT_PROPERTIES
-      ? 0 : other->inobject_properties();
+  int properties =
+      mode == CLEAR_INOBJECT_PROPERTIES ? 0 : other->GetInObjectProperties();
   return CheckEquivalent(this, other) && bit_field2() == other->bit_field2() &&
   return CheckEquivalent(this, other) && bit_field2() == other->bit_field2() &&
-         inobject_properties() == properties;
+         GetInObjectProperties() == properties;
 }
 
 
 }
 
 
@@ -9497,7 +9455,7 @@ static void GetMinInobjectSlack(Map* map, void* data) {
 
 static void ShrinkInstanceSize(Map* map, void* data) {
   int slack = *reinterpret_cast<int*>(data);
 
 static void ShrinkInstanceSize(Map* map, void* data) {
   int slack = *reinterpret_cast<int*>(data);
-  map->set_inobject_properties(map->inobject_properties() - slack);
+  map->SetInObjectProperties(map->GetInObjectProperties() - slack);
   map->set_unused_property_fields(map->unused_property_fields() - slack);
   map->set_instance_size(map->instance_size() - slack * kPointerSize);
 
   map->set_unused_property_fields(map->unused_property_fields() - slack);
   map->set_instance_size(map->instance_size() - slack * kPointerSize);
 
@@ -9979,7 +9937,7 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
   } else {
     prototype = isolate->factory()->NewFunctionPrototype(function);
   }
   } else {
     prototype = isolate->factory()->NewFunctionPrototype(function);
   }
-  map->set_inobject_properties(in_object_properties);
+  map->SetInObjectProperties(in_object_properties);
   map->set_unused_property_fields(in_object_properties);
   DCHECK(map->has_fast_object_elements());
 
   map->set_unused_property_fields(in_object_properties);
   DCHECK(map->has_fast_object_elements());
 
index 43e80c81561ca09ffa055868554be5ea9ecae491..cfcc3ec42d867c5c93b5456e119f90a9b974784a 100644 (file)
@@ -612,8 +612,8 @@ static inline bool IsShortcutCandidate(int type) {
 
 enum InstanceType {
   // String types.
 
 enum InstanceType {
   // String types.
-  INTERNALIZED_STRING_TYPE =
-      kTwoByteStringTag | kSeqStringTag | kInternalizedTag,
+  INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag |
+                             kInternalizedTag,  // FIRST_PRIMITIVE_TYPE
   ONE_BYTE_INTERNALIZED_STRING_TYPE =
       kOneByteStringTag | kSeqStringTag | kInternalizedTag,
   EXTERNAL_INTERNALIZED_STRING_TYPE =
   ONE_BYTE_INTERNALIZED_STRING_TYPE =
       kOneByteStringTag | kSeqStringTag | kInternalizedTag,
   EXTERNAL_INTERNALIZED_STRING_TYPE =
@@ -660,16 +660,18 @@ enum InstanceType {
   // Non-string names
   SYMBOL_TYPE = kNotStringTag,  // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
 
   // Non-string names
   SYMBOL_TYPE = kNotStringTag,  // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE
 
+  // Other primitives (cannot contain non-map-word pointers to heap objects).
+  HEAP_NUMBER_TYPE,
+  SIMD128_VALUE_TYPE,
+  ODDBALL_TYPE,  // LAST_PRIMITIVE_TYPE
+
   // Objects allocated in their own spaces (never in new space).
   MAP_TYPE,
   CODE_TYPE,
   // Objects allocated in their own spaces (never in new space).
   MAP_TYPE,
   CODE_TYPE,
-  ODDBALL_TYPE,
 
   // "Data", objects that cannot contain non-map-word pointers to heap
   // objects.
 
   // "Data", objects that cannot contain non-map-word pointers to heap
   // objects.
-  HEAP_NUMBER_TYPE,
   MUTABLE_HEAP_NUMBER_TYPE,
   MUTABLE_HEAP_NUMBER_TYPE,
-  SIMD128_VALUE_TYPE,
   FOREIGN_TYPE,
   BYTE_ARRAY_TYPE,
   BYTECODE_ARRAY_TYPE,
   FOREIGN_TYPE,
   BYTE_ARRAY_TYPE,
   BYTECODE_ARRAY_TYPE,
@@ -753,6 +755,8 @@ enum InstanceType {
   FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
   LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
   FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
   FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
   LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
   FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
+  FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE,
+  LAST_PRIMITIVE_TYPE = ODDBALL_TYPE,
   // Boundaries for testing for a fixed typed array.
   FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
   LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
   // Boundaries for testing for a fixed typed array.
   FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
   LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_UINT8_CLAMPED_ARRAY_TYPE,
@@ -5273,9 +5277,20 @@ class Map: public HeapObject {
   // Only to clear an unused byte, remove once byte is used.
   inline void clear_unused();
 
   // Only to clear an unused byte, remove once byte is used.
   inline void clear_unused();
 
-  // Count of properties allocated in the object.
-  inline int inobject_properties();
-  inline void set_inobject_properties(int value);
+  // [inobject_properties_or_constructor_function_index]: Provides access
+  // to the inobject properties in case of JSObject maps, or the constructor
+  // function index in case of primitive maps.
+  inline int inobject_properties_or_constructor_function_index();
+  inline void set_inobject_properties_or_constructor_function_index(int value);
+  // Count of properties allocated in the object (JSObject only).
+  inline int GetInObjectProperties();
+  inline void SetInObjectProperties(int value);
+  // Index of the constructor function in the native context (primitives only),
+  // or the special sentinel value to indicate that there is no object wrapper
+  // for the primitive (i.e. in case of null or undefined).
+  static const int kNoConstructorFunctionIndex = 0;
+  inline int GetConstructorFunctionIndex();
+  inline void SetConstructorFunctionIndex(int value);
 
   // Instance type.
   inline InstanceType instance_type();
 
   // Instance type.
   inline InstanceType instance_type();
@@ -5766,7 +5781,12 @@ class Map: public HeapObject {
     return instance_type() >= FIRST_JS_OBJECT_TYPE;
   }
 
     return instance_type() >= FIRST_JS_OBJECT_TYPE;
   }
 
+  bool IsPrimitiveMap() {
+    STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
+    return instance_type() <= LAST_PRIMITIVE_TYPE;
+  }
   bool IsJSObjectMap() {
   bool IsJSObjectMap() {
+    STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
     return instance_type() >= FIRST_JS_OBJECT_TYPE;
   }
   bool IsJSArrayMap() { return instance_type() == JS_ARRAY_TYPE; }
     return instance_type() >= FIRST_JS_OBJECT_TYPE;
   }
   bool IsJSArrayMap() { return instance_type() == JS_ARRAY_TYPE; }
@@ -5847,9 +5867,9 @@ class Map: public HeapObject {
 
   // Byte offsets within kInstanceSizesOffset.
   static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
 
   // Byte offsets within kInstanceSizesOffset.
   static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
-  static const int kInObjectPropertiesByte = 1;
-  static const int kInObjectPropertiesOffset =
-      kInstanceSizesOffset + kInObjectPropertiesByte;
+  static const int kInObjectPropertiesOrConstructorFunctionIndexByte = 1;
+  static const int kInObjectPropertiesOrConstructorFunctionIndexOffset =
+      kInstanceSizesOffset + kInObjectPropertiesOrConstructorFunctionIndexByte;
   // Note there is one byte available for use here.
   static const int kUnusedByte = 2;
   static const int kUnusedOffset = kInstanceSizesOffset + kUnusedByte;
   // Note there is one byte available for use here.
   static const int kUnusedByte = 2;
   static const int kUnusedOffset = kInstanceSizesOffset + kUnusedByte;
index 45a6c9ea694d6a5b0f00bb90a07d9325ece2cb6b..0bc781e34c005ceecf3aec2936553a5bc3eedce2 100644 (file)
@@ -434,7 +434,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ blt(&no_inobject_slack_tracking);
 
         // Allocate object with a slack.
         __ blt(&no_inobject_slack_tracking);
 
         // Allocate object with a slack.
-        __ lbz(r3, FieldMemOperand(r5, Map::kInObjectPropertiesOffset));
+        __ lbz(
+            r3,
+            FieldMemOperand(
+                r5, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset));
         __ lbz(r5, FieldMemOperand(r5, Map::kUnusedPropertyFieldsOffset));
         __ sub(r3, r3, r5);
         if (FLAG_debug_code) {
         __ lbz(r5, FieldMemOperand(r5, Map::kUnusedPropertyFieldsOffset));
         __ sub(r3, r3, r5);
         if (FLAG_debug_code) {
index 1ba1e34356caf5d93e425c7f3b0e6c337b655107..b8a97c79469bbae9c54225c6fdf9d11a9750acb8 100644 (file)
@@ -299,7 +299,7 @@ RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
 
 void Runtime::WeakCollectionInitialize(
     Isolate* isolate, Handle<JSWeakCollection> weak_collection) {
 
 void Runtime::WeakCollectionInitialize(
     Isolate* isolate, Handle<JSWeakCollection> weak_collection) {
-  DCHECK(weak_collection->map()->inobject_properties() == 0);
+  DCHECK_EQ(0, weak_collection->map()->GetInObjectProperties());
   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
   weak_collection->set_table(*table);
 }
   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
   weak_collection->set_table(*table);
 }
index 7b937fe3d2eb129b0d3a70546946d16cfdb5cd22..d7fca528017af6a2842f0fa752bcb728b59e0854 100644 (file)
@@ -1193,7 +1193,7 @@ RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
       FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
   if (field_index.is_inobject()) {
     RUNTIME_ASSERT(field_index.property_index() <
       FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
   if (field_index.is_inobject()) {
     RUNTIME_ASSERT(field_index.property_index() <
-                   object->map()->inobject_properties());
+                   object->map()->GetInObjectProperties());
   } else {
     RUNTIME_ASSERT(field_index.outobject_array_index() <
                    object->properties()->length());
   } else {
     RUNTIME_ASSERT(field_index.outobject_array_index() <
                    object->properties()->length());
index 94aa42c51aadb0a4881de57aa48fe2d6ab7e4ddc..55961c7ff059cc7ab9ddf31dd77599c0e587d70c 100644 (file)
@@ -225,7 +225,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ j(less, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
         __ j(less, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
-        __ movzxbp(rsi, FieldOperand(rax, Map::kInObjectPropertiesOffset));
+        __ movzxbp(
+            rsi,
+            FieldOperand(
+                rax, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset));
         __ movzxbp(rax, FieldOperand(rax, Map::kUnusedPropertyFieldsOffset));
         __ subp(rsi, rax);
         __ leap(rsi,
         __ movzxbp(rax, FieldOperand(rax, Map::kUnusedPropertyFieldsOffset));
         __ subp(rsi, rax);
         __ leap(rsi,
index 4fc08f5b94b2478ceeaa43d88a5fbefc1f2d9aa4..5d10684a22c955d227cb791ee5ea81412d48c096 100644 (file)
@@ -224,7 +224,10 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
         __ j(less, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
         __ j(less, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
-        __ movzx_b(esi, FieldOperand(eax, Map::kInObjectPropertiesOffset));
+        __ movzx_b(
+            esi,
+            FieldOperand(
+                eax, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset));
         __ movzx_b(eax, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));
         __ sub(esi, eax);
         __ lea(esi,
         __ movzx_b(eax, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));
         __ sub(esi, eax);
         __ lea(esi,
index 06fcd97a743b7dc5c0e81e5b1d7ad18404f038e9..1c09752b726e4a2cfe32ff36b698086edc60b78c 100644 (file)
@@ -1144,7 +1144,7 @@ TEST(Regression39128) {
   // Step 1: prepare a map for the object.  We add 1 inobject property to it.
   // Create a map with single inobject property.
   Handle<Map> my_map = Map::Create(CcTest::i_isolate(), 1);
   // Step 1: prepare a map for the object.  We add 1 inobject property to it.
   // Create a map with single inobject property.
   Handle<Map> my_map = Map::Create(CcTest::i_isolate(), 1);
-  int n_properties = my_map->inobject_properties();
+  int n_properties = my_map->GetInObjectProperties();
   CHECK_GT(n_properties, 0);
 
   int object_size = my_map->instance_size();
   CHECK_GT(n_properties, 0);
 
   int object_size = my_map->instance_size();
index 30c7ba833366fab4e49895686c3877cb782d9883..3a629bdca0e906e4e40babf18869d297f79f1eca 100644 (file)
@@ -634,7 +634,7 @@ static Handle<LayoutDescriptor> TestLayoutDescriptorAppend(
       descriptors->Append(&f);
 
       int field_index = f.GetDetails().field_index();
       descriptors->Append(&f);
 
       int field_index = f.GetDetails().field_index();
-      bool is_inobject = field_index < map->inobject_properties();
+      bool is_inobject = field_index < map->GetInObjectProperties();
       for (int bit = 0; bit < field_width_in_words; bit++) {
         CHECK_EQ(is_inobject && (kind == PROP_DOUBLE),
                  !layout_descriptor->IsTagged(field_index + bit));
       for (int bit = 0; bit < field_width_in_words; bit++) {
         CHECK_EQ(is_inobject && (kind == PROP_DOUBLE),
                  !layout_descriptor->IsTagged(field_index + bit));
@@ -763,7 +763,7 @@ static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull(
         int field_index = details.field_index();
         int field_width_in_words = details.field_width_in_words();
 
         int field_index = details.field_index();
         int field_width_in_words = details.field_width_in_words();
 
-        bool is_inobject = field_index < map->inobject_properties();
+        bool is_inobject = field_index < map->GetInObjectProperties();
         for (int bit = 0; bit < field_width_in_words; bit++) {
           CHECK_EQ(is_inobject && details.representation().IsDouble(),
                    !layout_desc->IsTagged(field_index + bit));
         for (int bit = 0; bit < field_width_in_words; bit++) {
           CHECK_EQ(is_inobject && details.representation().IsDouble(),
                    !layout_desc->IsTagged(field_index + bit));