Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2015-07-02 01:50:48 +0300
committerTrevor Norris <trev.norris@gmail.com>2015-07-02 02:01:03 +0300
commitbf7df17d25ff0e11d18edfe542586a99d8f96cf6 (patch)
tree2558409210d304f258d0a259c6414efaf956b3f2
parent483aac90531b1136da94dde1728e9a94e37fe565 (diff)
deps: upgrade v8 to 4.4.63.12
PR-URL: https://github.com/nodejs/io.js/pull/2092 Reviewed-By: Trevor Norris <trev.norris@gmail.com>
-rw-r--r--deps/v8/include/v8-version.h2
-rw-r--r--deps/v8/src/hydrogen.cc39
-rw-r--r--deps/v8/src/hydrogen.h3
-rw-r--r--deps/v8/src/objects-printer.cc1
-rw-r--r--deps/v8/src/objects.cc12
-rw-r--r--deps/v8/src/runtime/runtime-test.cc2
-rw-r--r--deps/v8/src/runtime/runtime-typedarray.cc10
-rw-r--r--deps/v8/test/cctest/test-migrations.cc112
8 files changed, 145 insertions, 36 deletions
diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h
index 35bfeb71087..2f2ea553338 100644
--- a/deps/v8/include/v8-version.h
+++ b/deps/v8/include/v8-version.h
@@ -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.)
diff --git a/deps/v8/src/hydrogen.cc b/deps/v8/src/hydrogen.cc
index f226730a2b7..a1b06482078 100644
--- a/deps/v8/src/hydrogen.cc
+++ b/deps/v8/src/hydrogen.cc
@@ -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);
}
diff --git a/deps/v8/src/hydrogen.h b/deps/v8/src/hydrogen.h
index 0feef24e6b9..eabcff4b7d0 100644
--- a/deps/v8/src/hydrogen.h
+++ b/deps/v8/src/hydrogen.h
@@ -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,
diff --git a/deps/v8/src/objects-printer.cc b/deps/v8/src/objects-printer.cc
index c9fdcd94ddf..aa4f4ded195 100644
--- a/deps/v8/src/objects-printer.cc
+++ b/deps/v8/src/objects-printer.cc
@@ -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";
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 8c14d057d2e..67a7b2bc7a1 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -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);
diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc
index ddf2e9d6b46..f590f81a2d8 100644
--- a/deps/v8/src/runtime/runtime-test.cc
+++ b/deps/v8/src/runtime/runtime-test.cc
@@ -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".
diff --git a/deps/v8/src/runtime/runtime-typedarray.cc b/deps/v8/src/runtime/runtime-typedarray.cc
index 10aba0cc424..fed6795509c 100644
--- a/deps/v8/src/runtime/runtime-typedarray.cc
+++ b/deps/v8/src/runtime/runtime-typedarray.cc
@@ -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);
}
diff --git a/deps/v8/test/cctest/test-migrations.cc b/deps/v8/test/cctest/test-migrations.cc
index 340e81d27ea..14bdcea3c68 100644
--- a/deps/v8/test/cctest/test-migrations.cc
+++ b/deps/v8/test/cctest/test-migrations.cc
@@ -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));
}
};