deps: upgrade v8 to 4.4.63.12
authorBen Noordhuis <info@bnoordhuis.nl>
Wed, 1 Jul 2015 22:50:48 +0000 (00:50 +0200)
committerRod Vagg <rod@vagg.org>
Tue, 4 Aug 2015 18:56:15 +0000 (11:56 -0700)
PR-URL: https://github.com/nodejs/io.js/pull/2092
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
deps/v8/include/v8-version.h
deps/v8/src/hydrogen.cc
deps/v8/src/hydrogen.h
deps/v8/src/objects-printer.cc
deps/v8/src/objects.cc
deps/v8/src/runtime/runtime-test.cc
deps/v8/src/runtime/runtime-typedarray.cc
deps/v8/test/cctest/test-migrations.cc
src/env-inl.h
src/node_buffer.cc

index 35bfeb7..2f2ea55 100644 (file)
@@ -11,7 +11,7 @@
 #define V8_MAJOR_VERSION 4
 #define V8_MINOR_VERSION 4
 #define V8_BUILD_NUMBER 63
-#define V8_PATCH_LEVEL 9
+#define V8_PATCH_LEVEL 12
 
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
index f226730..a1b0648 100644 (file)
@@ -9662,15 +9662,7 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
           HObjectAccess::ForMapAndOffset(initial_map,
                                          JSObject::kElementsOffset),
           empty_fixed_array);
-      if (initial_map->inobject_properties() != 0) {
-        HConstant* undefined = graph()->GetConstantUndefined();
-        for (int i = 0; i < initial_map->inobject_properties(); i++) {
-          int property_offset = initial_map->GetInObjectPropertyOffset(i);
-          Add<HStoreNamedField>(receiver,
-              HObjectAccess::ForMapAndOffset(initial_map, property_offset),
-              undefined);
-        }
-      }
+      BuildInitializeInobjectProperties(receiver, initial_map);
     }
 
     // Replace the constructor function with a newly allocated receiver using
@@ -9713,6 +9705,20 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
 }
 
 
+void HOptimizedGraphBuilder::BuildInitializeInobjectProperties(
+    HValue* receiver, Handle<Map> initial_map) {
+  if (initial_map->inobject_properties() != 0) {
+    HConstant* undefined = graph()->GetConstantUndefined();
+    for (int i = 0; i < initial_map->inobject_properties(); i++) {
+      int property_offset = initial_map->GetInObjectPropertyOffset(i);
+      Add<HStoreNamedField>(receiver, HObjectAccess::ForMapAndOffset(
+                                          initial_map, property_offset),
+                            undefined);
+    }
+  }
+}
+
+
 HValue* HGraphBuilder::BuildAllocateEmptyArrayBuffer(HValue* byte_length) {
   HAllocate* result =
       BuildAllocate(Add<HConstant>(JSArrayBuffer::kSizeWithInternalFields),
@@ -11282,13 +11288,13 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
     Handle<JSObject> boilerplate_object,
     AllocationSiteUsageContext* site_context) {
   NoObservableSideEffectsScope no_effects(this);
-  InstanceType instance_type = boilerplate_object->map()->instance_type();
+  Handle<Map> initial_map(boilerplate_object->map());
+  InstanceType instance_type = initial_map->instance_type();
   DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE);
 
   HType type = instance_type == JS_ARRAY_TYPE
       ? HType::JSArray() : HType::JSObject();
-  HValue* object_size_constant = Add<HConstant>(
-      boilerplate_object->map()->instance_size());
+  HValue* object_size_constant = Add<HConstant>(initial_map->instance_size());
 
   PretenureFlag pretenure_flag = NOT_TENURED;
   Handle<AllocationSite> current_site(*site_context->current(), isolate());
@@ -11313,6 +11319,11 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
 
   BuildEmitObjectHeader(boilerplate_object, object);
 
+  // Similarly to the elements pointer, there is no guarantee that all
+  // property allocations can get folded, so pre-initialize all in-object
+  // properties to a safe value.
+  BuildInitializeInobjectProperties(object, initial_map);
+
   Handle<FixedArrayBase> elements(boilerplate_object->elements());
   int elements_size = (elements->length() > 0 &&
       elements->map() != isolate()->heap()->fixed_cow_array_map()) ?
@@ -11351,8 +11362,8 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
   }
 
   // Copy in-object properties.
-  if (boilerplate_object->map()->NumberOfFields() != 0 ||
-      boilerplate_object->map()->unused_property_fields() > 0) {
+  if (initial_map->NumberOfFields() != 0 ||
+      initial_map->unused_property_fields() > 0) {
     BuildEmitInObjectProperties(boilerplate_object, object, site_context,
                                 pretenure_flag);
   }
index 0feef24..eabcff4 100644 (file)
@@ -2506,6 +2506,9 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
   void BuildInlinedCallArray(Expression* expression, int argument_count,
                              Handle<AllocationSite> site);
 
+  void BuildInitializeInobjectProperties(HValue* receiver,
+                                         Handle<Map> initial_map);
+
   class PropertyAccessInfo {
    public:
     PropertyAccessInfo(HOptimizedGraphBuilder* builder,
index c9fdcd9..aa4f4de 100644 (file)
@@ -415,6 +415,7 @@ void Map::MapPrint(std::ostream& os) {  // NOLINT
      << pre_allocated_property_fields() << "\n";
   os << " - unused property fields: " << unused_property_fields() << "\n";
   if (is_deprecated()) os << " - deprecated_map\n";
+  if (is_stable()) os << " - stable_map\n";
   if (is_dictionary_map()) os << " - dictionary_map\n";
   if (is_prototype_map()) {
     os << " - prototype_map\n";
index 8c14d05..67a7b2b 100644 (file)
@@ -2706,6 +2706,9 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
                  target_descriptors->GetFieldType(modify_index)));
     }
 #endif
+    if (*target_map != *old_map) {
+      old_map->NotifyLeafMapLayoutChange();
+    }
     return target_map;
   }
 
@@ -2959,13 +2962,6 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
       split_kind, old_descriptors->GetKey(split_nof), split_attributes,
       *new_descriptors, *new_layout_descriptor);
 
-  if (from_kind != to_kind) {
-    // There was an elements kind change in the middle of transition tree and
-    // we reconstructed the tree so that all elements kind transitions are
-    // done at the beginning, therefore the |old_map| is no longer stable.
-    old_map->NotifyLeafMapLayoutChange();
-  }
-
   // If |transition_target_deprecated| is true then the transition array
   // already contains entry for given descriptor. This means that the transition
   // could be inserted regardless of whether transitions array is full or not.
@@ -2976,6 +2972,8 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
                                             "GenAll_CantHaveMoreTransitions");
   }
 
+  old_map->NotifyLeafMapLayoutChange();
+
   if (FLAG_trace_generalization && modify_index >= 0) {
     PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
     PropertyDetails new_details = new_descriptors->GetDetails(modify_index);
index ddf2e9d..f590f81 100644 (file)
@@ -179,7 +179,7 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
       base::OS::Sleep(base::TimeDelta::FromMilliseconds(50));
     }
   }
-  if (FLAG_always_opt) {
+  if (FLAG_always_opt || FLAG_prepare_always_opt) {
     // With --always-opt, optimization status expectations might not
     // match up, so just return a sentinel.
     return Smi::FromInt(3);  // 3 == "always".
index 10aba0c..fed6795 100644 (file)
@@ -27,15 +27,15 @@ void Runtime::SetupArrayBuffer(Isolate* isolate,
   array_buffer->set_is_external(is_external);
   array_buffer->set_is_neuterable(true);
 
-  Handle<Object> byte_length =
-      isolate->factory()->NewNumberFromSize(allocated_length);
-  CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
-  array_buffer->set_byte_length(*byte_length);
-
   if (data && !is_external) {
     isolate->heap()->RegisterNewArrayBuffer(
         isolate->heap()->InNewSpace(*array_buffer), data, allocated_length);
   }
+
+  Handle<Object> byte_length =
+      isolate->factory()->NewNumberFromSize(allocated_length);
+  CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
+  array_buffer->set_byte_length(*byte_length);
 }
 
 
index 340e81d..14bdcea 100644 (file)
@@ -437,9 +437,9 @@ TEST(ReconfigureAccessorToNonExistingDataField) {
 
   Handle<Map> new_map = Map::ReconfigureProperty(
       map, 0, kData, NONE, Representation::None(), none_type, FORCE_FIELD);
-  // |map| did not change.
+  // |map| did not change except marked unstable.
   CHECK(!map->is_deprecated());
-  CHECK(map->is_stable());
+  CHECK(!map->is_stable());
   CHECK(expectations.Check(*map));
 
   expectations.SetDataField(0, NONE, Representation::None(), none_type);
@@ -601,12 +601,14 @@ static void TestGeneralizeRepresentation(
   CHECK(expectations.Check(*new_map));
 
   if (is_detached_map) {
+    CHECK(!map->is_stable());
     CHECK(map->is_deprecated());
     CHECK_NE(*map, *new_map);
     CHECK_EQ(expected_field_type_dependency && !field_owner->is_deprecated(),
              info.dependencies()->HasAborted());
 
   } else if (expected_deprecation) {
+    CHECK(!map->is_stable());
     CHECK(map->is_deprecated());
     CHECK(field_owner->is_deprecated());
     CHECK_NE(*map, *new_map);
@@ -614,6 +616,7 @@ static void TestGeneralizeRepresentation(
 
   } else {
     CHECK(!field_owner->is_deprecated());
+    CHECK(map->is_stable());  // Map did not change, must be left stable.
     CHECK_EQ(*map, *new_map);
 
     CHECK_EQ(expected_field_type_dependency, info.dependencies()->HasAborted());
@@ -654,6 +657,12 @@ static void TestGeneralizeRepresentation(
           to_type, expected_representation, expected_type, expected_deprecation,
           expected_field_type_dependency);
     }
+
+    // Check that reconfiguration to the very same field works correctly.
+    Representation representation = from_representation;
+    Handle<HeapType> type = from_type;
+    TestGeneralizeRepresentation(-1, 2, representation, type, representation,
+                                 type, representation, type, false, false);
   }
 }
 
@@ -877,6 +886,7 @@ TEST(GeneralizeRepresentationWithAccessorProperties) {
 
     expectations.SetDataField(i, Representation::Double(), any_type);
 
+    CHECK(!map->is_stable());
     CHECK(map->is_deprecated());
     CHECK_NE(*map, *new_map);
     CHECK(i == 0 || maps[i - 1]->is_deprecated());
@@ -962,7 +972,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
   Handle<Map> new_map =
       Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE);
 
-  // |map2| should be left unchanged.
+  // |map2| should be left unchanged but marked unstable.
+  CHECK(!map2->is_stable());
   CHECK(!map2->is_deprecated());
   CHECK_NE(*map2, *new_map);
   CHECK(expectations2.Check(*map2));
@@ -1047,7 +1058,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial(
   Handle<Map> new_map =
       Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE);
 
-  // |map2| should be left unchanged.
+  // |map2| should be left unchanged but marked unstable.
+  CHECK(!map2->is_stable());
   CHECK(!map2->is_deprecated());
   CHECK_NE(*map2, *new_map);
   CHECK(expectations2.Check(*map2));
@@ -1183,6 +1195,8 @@ struct CheckDeprecated {
 struct CheckSameMap {
   void Check(Handle<Map> map, Handle<Map> new_map,
              const Expectations& expectations) {
+    // |map| was not reconfigured, therefore it should stay stable.
+    CHECK(map->is_stable());
     CHECK(!map->is_deprecated());
     CHECK_EQ(*map, *new_map);
 
@@ -1196,6 +1210,21 @@ struct CheckSameMap {
 };
 
 
+// Checks that given |map| is NOT deprecated and matches expectations.
+// |new_map| is unrelated to |map|.
+struct CheckUnrelated {
+  void Check(Handle<Map> map, Handle<Map> new_map,
+             const Expectations& expectations) {
+    CHECK(!map->is_deprecated());
+    CHECK_NE(*map, *new_map);
+    CHECK(expectations.Check(*map));
+
+    CHECK(new_map->is_stable());
+    CHECK(!new_map->is_deprecated());
+  }
+};
+
+
 // Checks that given |map| is NOT deprecated, and |new_map| is a result of
 // copy-generalize-all-representations.
 struct CheckCopyGeneralizeAllRepresentations {
@@ -1289,7 +1318,8 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap(
   Handle<Map> new_map =
       Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE);
 
-  // |map2| should be left unchanged.
+  // |map2| should be left unchanged but marked unstable.
+  CHECK(!map2->is_stable());
   CHECK(!map2->is_deprecated());
   CHECK_NE(*map2, *new_map);
   CHECK(expectations2.Check(*map2));
@@ -1366,6 +1396,40 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) {
 }
 
 
+TEST(ReconfigureDataFieldAttribute_DataConstantToAccConstantAfterTargetMap) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  struct TestConfig {
+    Handle<JSFunction> js_func_;
+    Handle<AccessorPair> pair_;
+    TestConfig() {
+      Isolate* isolate = CcTest::i_isolate();
+      Factory* factory = isolate->factory();
+      js_func_ = factory->NewFunction(factory->empty_string());
+      pair_ = CreateAccessorPair(true, true);
+    }
+
+    Handle<Map> AddPropertyAtBranch(int branch_id, Expectations& expectations,
+                                    Handle<Map> map) {
+      CHECK(branch_id == 1 || branch_id == 2);
+      if (branch_id == 1) {
+        return expectations.AddDataConstant(map, NONE, js_func_);
+      } else {
+        return expectations.AddAccessorConstant(map, NONE, pair_);
+      }
+    }
+
+    void UpdateExpectations(int property_index, Expectations& expectations) {}
+  };
+
+  TestConfig config;
+  // These are completely separate branches in transition tree.
+  CheckUnrelated checker;
+  TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker);
+}
+
+
 TEST(ReconfigureDataFieldAttribute_SameAccessorConstantAfterTargetMap) {
   CcTest::InitializeVM();
   v8::HandleScope scope(CcTest::isolate());
@@ -1382,9 +1446,8 @@ TEST(ReconfigureDataFieldAttribute_SameAccessorConstantAfterTargetMap) {
       return expectations.AddAccessorConstant(map, NONE, pair_);
     }
 
-    bool UpdateExpectations(int property_index, Expectations& expectations) {
+    void UpdateExpectations(int property_index, Expectations& expectations) {
       // Two branches are "compatible" so the |map1| should NOT be deprecated.
-      return false;
     }
   };
 
@@ -1436,6 +1499,37 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) {
 }
 
 
+TEST(ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  struct TestConfig {
+    Handle<AccessorPair> pair_;
+    TestConfig() { pair_ = CreateAccessorPair(true, true); }
+
+    Handle<Map> AddPropertyAtBranch(int branch_id, Expectations& expectations,
+                                    Handle<Map> map) {
+      CHECK(branch_id == 1 || branch_id == 2);
+      if (branch_id == 1) {
+        return expectations.AddAccessorConstant(map, NONE, pair_);
+      } else {
+        Isolate* isolate = CcTest::i_isolate();
+        Handle<HeapType> any_type = HeapType::Any(isolate);
+        return expectations.AddDataField(map, NONE, Representation::Smi(),
+                                         any_type);
+      }
+    }
+
+    void UpdateExpectations(int property_index, Expectations& expectations) {}
+  };
+
+  TestConfig config;
+  // These are completely separate branches in transition tree.
+  CheckUnrelated checker;
+  TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker);
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 // A set of tests checking split map deprecation.
 //
@@ -1487,6 +1581,7 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) {
   // transition tree.
   CHECK(map->is_deprecated());
   CHECK(!split_map->is_deprecated());
+  CHECK(map2->is_stable());
   CHECK(!map2->is_deprecated());
 
   // Fill in transition tree of |map2| so that it can't have more transitions.
@@ -1932,7 +2027,8 @@ struct FieldGeneralizationChecker {
     Handle<Map> updated_map = Map::Update(map1);
     CHECK_EQ(*map2, *updated_map);
 
-    expectations2.SetDataField(descriptor_, representation_, heap_type_);
+    expectations2.SetDataField(descriptor_, attributes_, representation_,
+                               heap_type_);
     CHECK(expectations2.Check(*map2));
   }
 };
index 08d743f..369bc2f 100644 (file)
@@ -172,7 +172,6 @@ inline Environment::Environment(v8::Local<v8::Context> context,
     : isolate_(context->GetIsolate()),
       isolate_data_(IsolateData::GetOrCreate(context->GetIsolate(), loop)),
       timer_base_(uv_now(loop)),
-      using_smalloc_alloc_cb_(false),
       using_domains_(false),
       using_abort_on_uncaught_exc_(false),
       using_asyncwrap_(false),
@@ -293,14 +292,6 @@ inline uint64_t Environment::timer_base() const {
   return timer_base_;
 }
 
-inline bool Environment::using_smalloc_alloc_cb() const {
-  return using_smalloc_alloc_cb_;
-}
-
-inline void Environment::set_using_smalloc_alloc_cb(bool value) {
-  using_smalloc_alloc_cb_ = value;
-}
-
 inline bool Environment::using_abort_on_uncaught_exc() const {
   return using_abort_on_uncaught_exc_;
 }
index c4a0f67..b09f733 100644 (file)
@@ -485,7 +485,6 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
   Isolate* isolate = env->isolate();
 
   THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
-
   SPREAD_ARG(args.This(), ts_obj);
 
   if (ts_obj_length == 0)
@@ -503,9 +502,7 @@ void StringSlice<UCS2>(const FunctionCallbackInfo<Value>& args) {
   Environment* env = Environment::GetCurrent(args);
 
   THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
-
   SPREAD_ARG(args.This(), ts_obj);
-  SLICE_START_END(args[0], args[1], ts_obj_length)
 
   if (ts_obj_length == 0)
     return args.GetReturnValue().SetEmptyString();
@@ -579,9 +576,7 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
 
   THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
   THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
-
-  Local<Object> target_obj = args[0]->ToObject(env->isolate());
-
+  Local<Object> target_obj = args[0].As<Object>();
   SPREAD_ARG(args.This(), ts_obj);
   SPREAD_ARG(target_obj, target);
 
@@ -834,7 +829,6 @@ void Compare(const FunctionCallbackInfo<Value> &args) {
 
   THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
   THROW_AND_RETURN_UNLESS_BUFFER(env, args[1]);
-
   SPREAD_ARG(args[0], obj_a);
   SPREAD_ARG(args[1], obj_b);