Browse Source

deps: upgrade to V8 5.0.71.54

PR-URL: https://github.com/nodejs/node/pull/7531
Reviewed-By: Michaël Zasso <mic.besace@gmail.com>
v6.x
Ben Noordhuis 9 years ago
parent
commit
dbdcded866
  1. 2
      deps/v8/include/v8-version.h
  2. 4
      deps/v8/src/bootstrapper.cc
  3. 68
      deps/v8/src/builtins.cc
  4. 2
      deps/v8/src/builtins.h
  5. 8
      deps/v8/src/compiler/access-info.cc
  6. 10
      deps/v8/src/crankshaft/hydrogen.cc
  7. 7
      deps/v8/src/ic/ic-compiler.cc
  8. 11
      deps/v8/src/ic/ic.cc
  9. 13
      deps/v8/src/js/string.js
  10. 20
      deps/v8/src/objects-inl.h
  11. 154
      deps/v8/src/objects.cc
  12. 53
      deps/v8/src/objects.h
  13. 320
      deps/v8/test/cctest/test-field-type-tracking.cc
  14. 22
      deps/v8/test/cctest/test-strings.cc
  15. 18
      deps/v8/test/mjsunit/regress/regress-crbug-617524.js
  16. 34
      deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex2.js
  17. 61
      deps/v8/test/mjsunit/regress/regress-v8-5009.js
  18. 5
      deps/v8/test/mjsunit/string-fromcharcode.js

2
deps/v8/include/v8-version.h

@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 5
#define V8_MINOR_VERSION 0
#define V8_BUILD_NUMBER 71
#define V8_PATCH_LEVEL 52
#define V8_PATCH_LEVEL 54
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)

4
deps/v8/src/bootstrapper.cc

@ -1292,6 +1292,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
attribs);
string_map->AppendDescriptor(&d);
}
// Install the String.fromCharCode function.
SimpleInstallFunction(string_fun, "fromCharCode",
Builtins::kStringFromCharCode, 1, false);
}
{

68
deps/v8/src/builtins.cc

@ -3732,6 +3732,74 @@ BUILTIN(ObjectProtoToString) {
return *result;
}
// -----------------------------------------------------------------------------
// ES6 section 21.1 String Objects
namespace {
bool ToUint16(Handle<Object> value, uint16_t* result) {
if (value->IsNumber() || Object::ToNumber(value).ToHandle(&value)) {
*result = DoubleToUint32(value->Number());
return true;
}
return false;
}
} // namespace
// ES6 21.1.2.1 String.fromCharCode ( ...codeUnits )
BUILTIN(StringFromCharCode) {
HandleScope scope(isolate);
// Check resulting string length.
int index = 0;
Handle<String> result;
int const length = args.length() - 1;
if (length == 0) return isolate->heap()->empty_string();
DCHECK_LT(0, length);
// Load the first character code.
uint16_t code;
if (!ToUint16(args.at<Object>(1), &code)) return isolate->heap()->exception();
// Assume that the resulting String contains only one byte characters.
if (code <= String::kMaxOneByteCharCodeU) {
// Check for single one-byte character fast case.
if (length == 1) {
return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
}
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, isolate->factory()->NewRawOneByteString(length));
do {
Handle<SeqOneByteString>::cast(result)->Set(index, code);
if (++index == length) break;
if (!ToUint16(args.at<Object>(1 + index), &code)) {
return isolate->heap()->exception();
}
} while (code <= String::kMaxOneByteCharCodeU);
}
// Check if all characters fit into the one byte range.
if (index < length) {
// Fallback to two byte string.
Handle<String> new_result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, new_result, isolate->factory()->NewRawTwoByteString(length));
for (int new_index = 0; new_index < index; ++new_index) {
uint16_t new_code =
Handle<SeqOneByteString>::cast(result)->Get(new_index);
Handle<SeqTwoByteString>::cast(new_result)->Set(new_index, new_code);
}
while (true) {
Handle<SeqTwoByteString>::cast(new_result)->Set(index, code);
if (++index == length) break;
if (!ToUint16(args.at<Object>(1 + index), &code)) {
return isolate->heap()->exception();
}
}
result = new_result;
}
return *result;
}
// -----------------------------------------------------------------------------
// ES6 section 21.1 ArrayBuffer Objects
// ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case.
BUILTIN(ArrayBufferConstructor) {

2
deps/v8/src/builtins.h

@ -149,6 +149,8 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
V(ReflectSet, kNone) \
V(ReflectSetPrototypeOf, kNone) \
\
V(StringFromCharCode, kNone) \
\
V(SymbolConstructor, kNone) \
V(SymbolConstructor_ConstructStub, kTarget) \
\

8
deps/v8/src/compiler/access-info.cc

@ -192,12 +192,12 @@ bool AccessInfoFactory::ComputeElementAccessInfos(
MapTransitionList transitions(maps.length());
for (Handle<Map> map : maps) {
if (Map::TryUpdate(map).ToHandle(&map)) {
Handle<Map> transition_target =
Map::FindTransitionedMap(map, &possible_transition_targets);
if (transition_target.is_null()) {
Map* transition_target =
map->FindElementsKindTransitionedMap(&possible_transition_targets);
if (transition_target == nullptr) {
receiver_maps.Add(map);
} else {
transitions.push_back(std::make_pair(map, transition_target));
transitions.push_back(std::make_pair(map, handle(transition_target)));
}
}
}

10
deps/v8/src/crankshaft/hydrogen.cc

@ -7600,9 +7600,13 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
// Get transition target for each map (NULL == no transition).
for (int i = 0; i < maps->length(); ++i) {
Handle<Map> map = maps->at(i);
Handle<Map> transitioned_map =
Map::FindTransitionedMap(map, &possible_transitioned_maps);
transition_target.Add(transitioned_map);
Map* transitioned_map =
map->FindElementsKindTransitionedMap(&possible_transitioned_maps);
if (transitioned_map != nullptr) {
transition_target.Add(handle(transitioned_map));
} else {
transition_target.Add(Handle<Map>());
}
}
MapHandleList untransitionable_maps(maps->length());

7
deps/v8/src/ic/ic-compiler.cc

@ -235,8 +235,11 @@ void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers(
for (int i = 0; i < receiver_maps->length(); ++i) {
Handle<Map> receiver_map(receiver_maps->at(i));
Handle<Code> cached_stub;
Handle<Map> transitioned_map =
Map::FindTransitionedMap(receiver_map, receiver_maps);
Handle<Map> transitioned_map;
{
Map* tmap = receiver_map->FindElementsKindTransitionedMap(receiver_maps);
if (tmap != nullptr) transitioned_map = handle(tmap);
}
// TODO(mvstanton): The code below is doing pessimistic elements
// transitions. I would like to stop doing that and rely on Allocation Site

11
deps/v8/src/ic/ic.cc

@ -836,11 +836,12 @@ bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
ElementsKind target_elements_kind = target_map->elements_kind();
bool more_general_transition = IsMoreGeneralElementsKindTransition(
source_map->elements_kind(), target_elements_kind);
Map* transitioned_map =
more_general_transition
? source_map->LookupElementsTransitionMap(target_elements_kind)
: NULL;
Map* transitioned_map = nullptr;
if (more_general_transition) {
MapHandleList map_list;
map_list.Add(handle(target_map));
transitioned_map = source_map->FindElementsKindTransitionedMap(&map_list);
}
return transitioned_map == target_map;
}

13
deps/v8/src/js/string.js

@ -558,18 +558,6 @@ function StringTrimRight() {
}
// ECMA-262, section 15.5.3.2
function StringFromCharCode(_) { // length == 1
"use strict";
var s = "";
var n = arguments.length;
for (var i = 0; i < n; ++i) {
s += %_StringCharFromCode(arguments[i] & 0xffff);
}
return s;
}
// ES6 draft, revision 26 (2014-07-18), section B.2.3.2.1
function HtmlEscape(str) {
return %_Call(StringReplace, TO_STRING(str), /"/g, "&quot;");
@ -860,7 +848,6 @@ function StringRaw(callSite) {
// Set up the non-enumerable functions on the String object.
utils.InstallFunctions(GlobalString, DONT_ENUM, [
"fromCharCode", StringFromCharCode,
"fromCodePoint", StringFromCodePoint,
"raw", StringRaw
]);

20
deps/v8/src/objects-inl.h

@ -18,6 +18,7 @@
#include "src/conversions-inl.h"
#include "src/factory.h"
#include "src/field-index-inl.h"
#include "src/field-type.h"
#include "src/handles-inl.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
@ -2724,6 +2725,25 @@ FixedArrayBase* Map::GetInitialElements() {
return NULL;
}
// static
Handle<Map> Map::ReconfigureProperty(Handle<Map> map, int modify_index,
PropertyKind new_kind,
PropertyAttributes new_attributes,
Representation new_representation,
Handle<FieldType> new_field_type,
StoreMode store_mode) {
return Reconfigure(map, map->elements_kind(), modify_index, new_kind,
new_attributes, new_representation, new_field_type,
store_mode);
}
// static
Handle<Map> Map::ReconfigureElementsKind(Handle<Map> map,
ElementsKind new_elements_kind) {
return Reconfigure(map, new_elements_kind, -1, kData, NONE,
Representation::None(), FieldType::None(map->GetIsolate()),
ALLOW_IN_DESCRIPTOR);
}
Object** DescriptorArray::GetKeySlot(int descriptor_number) {
DCHECK(descriptor_number < number_of_descriptors());

154
deps/v8/src/objects.cc

@ -2681,6 +2681,16 @@ const char* Representation::Mnemonic() const {
}
}
bool Map::InstancesNeedRewriting(Map* target) {
int target_number_of_fields = target->NumberOfFields();
int target_inobject = target->GetInObjectProperties();
int target_unused = target->unused_property_fields();
int old_number_of_fields;
return InstancesNeedRewriting(target, target_number_of_fields,
target_inobject, target_unused,
&old_number_of_fields);
}
bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
int target_inobject, int target_unused,
@ -3141,10 +3151,10 @@ int Map::NumberOfFields() {
return result;
}
Handle<Map> Map::CopyGeneralizeAllRepresentations(
Handle<Map> map, int modify_index, StoreMode store_mode, PropertyKind kind,
PropertyAttributes attributes, const char* reason) {
Handle<Map> map, ElementsKind elements_kind, int modify_index,
StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes,
const char* reason) {
Isolate* isolate = map->GetIsolate();
Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
int number_of_own_descriptors = map->NumberOfOwnDescriptors();
@ -3200,6 +3210,7 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(
MaybeHandle<Object>());
}
}
new_map->set_elements_kind(elements_kind);
return new_map;
}
@ -3437,9 +3448,9 @@ static inline Handle<FieldType> GetFieldType(
}
}
// Reconfigures property at |modify_index| with |new_kind|, |new_attributes|,
// |store_mode| and/or |new_representation|/|new_field_type|.
// Reconfigures elements kind to |new_elements_kind| and/or property at
// |modify_index| with |new_kind|, |new_attributes|, |store_mode| and/or
// |new_representation|/|new_field_type|.
// If |modify_index| is negative then no properties are reconfigured but the
// map is migrated to the up-to-date non-deprecated state.
//
@ -3449,6 +3460,7 @@ static inline Handle<FieldType> GetFieldType(
// any potential new (partial) version of the type in the transition tree.
// To do this, on each rewrite:
// - Search the root of the transition tree using FindRootMap.
// - Find/create a |root_map| with requested |new_elements_kind|.
// - Find |target_map|, the newest matching version of this map using the
// virtually "enhanced" |old_map|'s descriptor array (i.e. whose entry at
// |modify_index| is considered to be of |new_kind| and having
@ -3464,12 +3476,13 @@ static inline Handle<FieldType> GetFieldType(
// Return it.
// - Otherwise, invalidate the outdated transition target from |target_map|, and
// replace its transition tree with a new branch for the updated descriptors.
Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
PropertyKind new_kind,
PropertyAttributes new_attributes,
Representation new_representation,
Handle<FieldType> new_field_type,
StoreMode store_mode) {
Handle<Map> Map::Reconfigure(Handle<Map> old_map,
ElementsKind new_elements_kind, int modify_index,
PropertyKind new_kind,
PropertyAttributes new_attributes,
Representation new_representation,
Handle<FieldType> new_field_type,
StoreMode store_mode) {
DCHECK_NE(kAccessor, new_kind); // TODO(ishell): not supported yet.
DCHECK(store_mode != FORCE_FIELD || modify_index >= 0);
Isolate* isolate = old_map->GetIsolate();
@ -3484,7 +3497,8 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
// uninitialized value for representation None can be overwritten by both
// smi and tagged values. Doubles, however, would require a box allocation.
if (modify_index >= 0 && !new_representation.IsNone() &&
!new_representation.IsDouble()) {
!new_representation.IsDouble() &&
old_map->elements_kind() == new_elements_kind) {
PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
Representation old_representation = old_details.representation();
@ -3517,38 +3531,39 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
// Check the state of the root map.
Handle<Map> root_map(old_map->FindRootMap(), isolate);
if (!old_map->EquivalentToForTransition(*root_map)) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
new_kind, new_attributes,
"GenAll_NotEquivalent");
return CopyGeneralizeAllRepresentations(
old_map, new_elements_kind, modify_index, store_mode, new_kind,
new_attributes, "GenAll_NotEquivalent");
}
ElementsKind from_kind = root_map->elements_kind();
ElementsKind to_kind = old_map->elements_kind();
ElementsKind to_kind = new_elements_kind;
// TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS.
if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS &&
to_kind != SLOW_STRING_WRAPPER_ELEMENTS &&
to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS &&
!(IsTransitionableFastElementsKind(from_kind) &&
IsMoreGeneralElementsKindTransition(from_kind, to_kind))) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
new_kind, new_attributes,
"GenAll_InvalidElementsTransition");
return CopyGeneralizeAllRepresentations(
old_map, to_kind, modify_index, store_mode, new_kind, new_attributes,
"GenAll_InvalidElementsTransition");
}
int root_nof = root_map->NumberOfOwnDescriptors();
if (modify_index >= 0 && modify_index < root_nof) {
PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
if (old_details.kind() != new_kind ||
old_details.attributes() != new_attributes) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
new_kind, new_attributes,
"GenAll_RootModification1");
return CopyGeneralizeAllRepresentations(
old_map, to_kind, modify_index, store_mode, new_kind, new_attributes,
"GenAll_RootModification1");
}
if ((old_details.type() != DATA && store_mode == FORCE_FIELD) ||
(old_details.type() == DATA &&
(!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) ||
!new_representation.fits_into(old_details.representation())))) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
new_kind, new_attributes,
"GenAll_RootModification2");
return CopyGeneralizeAllRepresentations(
old_map, to_kind, modify_index, store_mode, new_kind, new_attributes,
"GenAll_RootModification2");
}
}
@ -3602,9 +3617,9 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
if (next_kind == kAccessor &&
!EqualImmutableValues(old_descriptors->GetValue(i),
tmp_descriptors->GetValue(i))) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
new_kind, new_attributes,
"GenAll_Incompatible");
return CopyGeneralizeAllRepresentations(
old_map, to_kind, modify_index, store_mode, new_kind, new_attributes,
"GenAll_Incompatible");
}
if (next_location == kField && tmp_details.location() == kDescriptor) break;
@ -3697,9 +3712,9 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
if (next_kind == kAccessor &&
!EqualImmutableValues(old_descriptors->GetValue(i),
tmp_descriptors->GetValue(i))) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
new_kind, new_attributes,
"GenAll_Incompatible");
return CopyGeneralizeAllRepresentations(
old_map, to_kind, modify_index, store_mode, new_kind, new_attributes,
"GenAll_Incompatible");
}
DCHECK(!tmp_map->is_deprecated());
target_map = tmp_map;
@ -3930,9 +3945,9 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
// could be inserted regardless of whether transitions array is full or not.
if (maybe_transition == NULL &&
!TransitionArray::CanHaveMoreTransitions(split_map)) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
new_kind, new_attributes,
"GenAll_CantHaveMoreTransitions");
return CopyGeneralizeAllRepresentations(
old_map, to_kind, modify_index, store_mode, new_kind, new_attributes,
"GenAll_CantHaveMoreTransitions");
}
old_map->NotifyLeafMapLayoutChange();
@ -4013,18 +4028,27 @@ MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
if (root_map == NULL) return MaybeHandle<Map>();
// From here on, use the map with correct elements kind as root map.
}
int root_nof = root_map->NumberOfOwnDescriptors();
Map* new_map = root_map->TryReplayPropertyTransitions(*old_map);
if (new_map == nullptr) return MaybeHandle<Map>();
return handle(new_map);
}
Map* Map::TryReplayPropertyTransitions(Map* old_map) {
DisallowHeapAllocation no_allocation;
DisallowDeoptimization no_deoptimization(GetIsolate());
int root_nof = NumberOfOwnDescriptors();
int old_nof = old_map->NumberOfOwnDescriptors();
DescriptorArray* old_descriptors = old_map->instance_descriptors();
Map* new_map = root_map;
Map* new_map = this;
for (int i = root_nof; i < old_nof; ++i) {
PropertyDetails old_details = old_descriptors->GetDetails(i);
Map* transition = TransitionArray::SearchTransition(
new_map, old_details.kind(), old_descriptors->GetKey(i),
old_details.attributes());
if (transition == NULL) return MaybeHandle<Map>();
if (transition == NULL) return nullptr;
new_map = transition;
DescriptorArray* new_descriptors = new_map->instance_descriptors();
@ -4032,7 +4056,7 @@ MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
DCHECK_EQ(old_details.kind(), new_details.kind());
DCHECK_EQ(old_details.attributes(), new_details.attributes());
if (!old_details.representation().fits_into(new_details.representation())) {
return MaybeHandle<Map>();
return nullptr;
}
switch (new_details.type()) {
case DATA: {
@ -4040,20 +4064,20 @@ MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
// Cleared field types need special treatment. They represent lost
// knowledge, so we must first generalize the new_type to "Any".
if (FieldTypeIsCleared(new_details.representation(), new_type)) {
return MaybeHandle<Map>();
return nullptr;
}
PropertyType old_property_type = old_details.type();
if (old_property_type == DATA) {
FieldType* old_type = old_descriptors->GetFieldType(i);
if (FieldTypeIsCleared(old_details.representation(), old_type) ||
!old_type->NowIs(new_type)) {
return MaybeHandle<Map>();
return nullptr;
}
} else {
DCHECK(old_property_type == DATA_CONSTANT);
Object* old_value = old_descriptors->GetValue(i);
if (!new_type->NowContains(old_value)) {
return MaybeHandle<Map>();
return nullptr;
}
}
break;
@ -4071,14 +4095,14 @@ MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map) {
Object* old_value = old_descriptors->GetValue(i);
Object* new_value = new_descriptors->GetValue(i);
if (old_details.location() == kField || old_value != new_value) {
return MaybeHandle<Map>();
return nullptr;
}
break;
}
}
}
if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>();
return handle(new_map);
if (new_map->NumberOfOwnDescriptors() != old_nof) return nullptr;
return new_map;
}
@ -4736,17 +4760,30 @@ static bool ContainsMap(MapHandleList* maps, Map* map) {
return false;
}
Map* Map::FindElementsKindTransitionedMap(MapHandleList* candidates) {
DisallowHeapAllocation no_allocation;
DisallowDeoptimization no_deoptimization(GetIsolate());
Handle<Map> Map::FindTransitionedMap(Handle<Map> map,
MapHandleList* candidates) {
ElementsKind kind = map->elements_kind();
ElementsKind kind = elements_kind();
bool packed = IsFastPackedElementsKind(kind);
Map* transition = nullptr;
if (IsTransitionableFastElementsKind(kind)) {
for (Map* current = map->ElementsTransitionMap();
current != nullptr && current->has_fast_elements();
current = current->ElementsTransitionMap()) {
// Check the state of the root map.
Map* root_map = FindRootMap();
if (!EquivalentToForTransition(root_map)) return nullptr;
root_map = root_map->LookupElementsTransitionMap(kind);
DCHECK_NOT_NULL(root_map);
// Starting from the next existing elements kind transition try to
// replay the property transitions that does not involve instance rewriting
// (ElementsTransitionAndStoreStub does not support that).
for (root_map = root_map->ElementsTransitionMap();
root_map != nullptr && root_map->has_fast_elements();
root_map = root_map->ElementsTransitionMap()) {
Map* current = root_map->TryReplayPropertyTransitions(this);
if (current == nullptr) continue;
if (InstancesNeedRewriting(current)) continue;
if (ContainsMap(candidates, current) &&
(packed || !IsFastPackedElementsKind(current->elements_kind()))) {
transition = current;
@ -4754,11 +4791,14 @@ Handle<Map> Map::FindTransitionedMap(Handle<Map> map,
}
}
}
return transition == nullptr ? Handle<Map>() : handle(transition);
return transition;
}
static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
// Ensure we are requested to search elements kind transition "near the root".
DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(),
map->NumberOfOwnDescriptors());
Map* current_map = map;
ElementsKind kind = map->elements_kind();
@ -4889,7 +4929,7 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
return Map::CopyAsElementsKind(map, to_kind, OMIT_TRANSITION);
}
return Map::AsElementsKind(map, to_kind);
return Map::ReconfigureElementsKind(map, to_kind);
}
@ -5215,7 +5255,7 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
} else {
TransitionElementsKind(object, to_kind);
}
map = Map::AsElementsKind(map, to_kind);
map = Map::ReconfigureElementsKind(map, to_kind);
}
JSObject::MigrateToMap(object, map);
}
@ -9563,6 +9603,10 @@ Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind,
TransitionFlag flag) {
Map* maybe_elements_transition_map = NULL;
if (flag == INSERT_TRANSITION) {
// Ensure we are requested to add elements kind transition "near the root".
DCHECK_EQ(map->FindRootMap()->NumberOfOwnDescriptors(),
map->NumberOfOwnDescriptors());
maybe_elements_transition_map = map->ElementsTransitionMap();
DCHECK(maybe_elements_transition_map == NULL ||
(maybe_elements_transition_map->elements_kind() ==
@ -9890,7 +9934,7 @@ Handle<Map> Map::ReconfigureExistingProperty(Handle<Map> map, int descriptor,
// There is no benefit from reconstructing transition tree for maps without
// back pointers.
return CopyGeneralizeAllRepresentations(
map, descriptor, FORCE_FIELD, kind, attributes,
map, map->elements_kind(), descriptor, FORCE_FIELD, kind, attributes,
"GenAll_AttributesMismatchProtoMap");
}

53
deps/v8/src/objects.h

@ -5773,6 +5773,7 @@ class Map: public HeapObject {
int NumberOfFields();
// TODO(ishell): candidate with JSObject::MigrateToMap().
bool InstancesNeedRewriting(Map* target);
bool InstancesNeedRewriting(Map* target, int target_number_of_fields,
int target_inobject, int target_unused,
int* old_number_of_fields);
@ -5784,15 +5785,14 @@ class Map: public HeapObject {
static void GeneralizeFieldType(Handle<Map> map, int modify_index,
Representation new_representation,
Handle<FieldType> new_field_type);
static Handle<Map> ReconfigureProperty(Handle<Map> map, int modify_index,
PropertyKind new_kind,
PropertyAttributes new_attributes,
Representation new_representation,
Handle<FieldType> new_field_type,
StoreMode store_mode);
static Handle<Map> CopyGeneralizeAllRepresentations(
Handle<Map> map, int modify_index, StoreMode store_mode,
PropertyKind kind, PropertyAttributes attributes, const char* reason);
static inline Handle<Map> ReconfigureProperty(
Handle<Map> map, int modify_index, PropertyKind new_kind,
PropertyAttributes new_attributes, Representation new_representation,
Handle<FieldType> new_field_type, StoreMode store_mode);
static inline Handle<Map> ReconfigureElementsKind(
Handle<Map> map, ElementsKind new_elements_kind);
static Handle<Map> PrepareForDataProperty(Handle<Map> old_map,
int descriptor_number,
@ -6022,17 +6022,10 @@ class Map: public HeapObject {
// Computes a hash value for this map, to be used in HashTables and such.
int Hash();
// Returns the map that this map transitions to if its elements_kind
// is changed to |elements_kind|, or NULL if no such map is cached yet.
// |safe_to_add_transitions| is set to false if adding transitions is not
// allowed.
Map* LookupElementsTransitionMap(ElementsKind elements_kind);
// Returns the transitioned map for this map with the most generic
// elements_kind that's found in |candidates|, or null handle if no match is
// elements_kind that's found in |candidates|, or |nullptr| if no match is
// found at all.
static Handle<Map> FindTransitionedMap(Handle<Map> map,
MapHandleList* candidates);
Map* FindElementsKindTransitionedMap(MapHandleList* candidates);
inline bool CanTransition();
@ -6191,6 +6184,17 @@ class Map: public HeapObject {
Handle<LayoutDescriptor> full_layout_descriptor);
private:
// Returns the map that this (root) map transitions to if its elements_kind
// is changed to |elements_kind|, or |nullptr| if no such map is cached yet.
Map* LookupElementsTransitionMap(ElementsKind elements_kind);
// Tries to replay property transitions starting from this (root) map using
// the descriptor array of the |map|. The |root_map| is expected to have
// proper elements kind and therefore elements kinds transitions are not
// taken by this function. Returns |nullptr| if matching transition map is
// not found.
Map* TryReplayPropertyTransitions(Map* map);
static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
Handle<Name> name, SimpleTransitionFlag flag);
@ -6227,6 +6231,19 @@ class Map: public HeapObject {
static Handle<Map> CopyNormalized(Handle<Map> map,
PropertyNormalizationMode mode);
static Handle<Map> Reconfigure(Handle<Map> map,
ElementsKind new_elements_kind,
int modify_index, PropertyKind new_kind,
PropertyAttributes new_attributes,
Representation new_representation,
Handle<FieldType> new_field_type,
StoreMode store_mode);
static Handle<Map> CopyGeneralizeAllRepresentations(
Handle<Map> map, ElementsKind elements_kind, int modify_index,
StoreMode store_mode, PropertyKind kind, PropertyAttributes attributes,
const char* reason);
// Fires when the layout of an object with a leaf map changes.
// This includes adding transitions to the leaf map or changing
// the descriptor array.

320
deps/v8/test/cctest/test-field-type-tracking.cc

@ -86,6 +86,7 @@ static bool EqualDetails(DescriptorArray* descriptors, int descriptor,
class Expectations {
static const int MAX_PROPERTIES = 10;
Isolate* isolate_;
ElementsKind elements_kind_;
PropertyType types_[MAX_PROPERTIES];
PropertyAttributes attributes_[MAX_PROPERTIES];
Representation representations_[MAX_PROPERTIES];
@ -97,8 +98,15 @@ class Expectations {
int number_of_properties_;
public:
explicit Expectations(Isolate* isolate, ElementsKind elements_kind)
: isolate_(isolate),
elements_kind_(elements_kind),
number_of_properties_(0) {}
explicit Expectations(Isolate* isolate)
: isolate_(isolate), number_of_properties_(0) {}
: Expectations(
isolate,
isolate->object_function()->initial_map()->elements_kind()) {}
void Init(int index, PropertyType type, PropertyAttributes attributes,
Representation representation, Handle<Object> value) {
@ -143,6 +151,10 @@ class Expectations {
os << "\n";
}
void SetElementsKind(ElementsKind elements_kind) {
elements_kind_ = elements_kind;
}
Handle<FieldType> GetFieldType(int index) {
CHECK(index < MAX_PROPERTIES);
CHECK(types_[index] == DATA || types_[index] == ACCESSOR);
@ -252,6 +264,7 @@ class Expectations {
}
bool Check(Map* map, int expected_nof) const {
CHECK_EQ(elements_kind_, map->elements_kind());
CHECK(number_of_properties_ <= MAX_PROPERTIES);
CHECK_EQ(expected_nof, map->NumberOfOwnDescriptors());
CHECK(!map->is_dictionary_map());
@ -279,6 +292,13 @@ class Expectations {
// given |map|.
//
Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind elements_kind) {
elements_kind_ = elements_kind;
map = Map::AsElementsKind(map, elements_kind);
CHECK_EQ(elements_kind_, map->elements_kind());
return map;
}
Handle<Map> AddDataField(Handle<Map> map, PropertyAttributes attributes,
Representation representation,
Handle<FieldType> heap_type) {
@ -1524,6 +1544,271 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) {
}
////////////////////////////////////////////////////////////////////////////////
// A set of tests for elements kind reconfiguration case.
//
// This test ensures that representation/field type generalization is correctly
// propagated from one branch of transition tree (|map2) to another (|map|).
//
// + - p0 - p1 - p2A - p3 - p4: |map|
// |
// ek
// |
// {} - p0 - p1 - p2B - p3 - p4: |map2|
//
// where "p2A" and "p2B" differ only in the representation/field type.
//
static void TestReconfigureElementsKind_GeneralizeRepresentation(
Representation from_representation, Handle<FieldType> from_type,
Representation to_representation, Handle<FieldType> to_type,
Representation expected_representation, Handle<FieldType> expected_type) {
Isolate* isolate = CcTest::i_isolate();
Expectations expectations(isolate, FAST_SMI_ELEMENTS);
// Create a map, add required properties to it and initialize expectations.
Handle<Map> initial_map = Map::Create(isolate, 0);
initial_map->set_elements_kind(FAST_SMI_ELEMENTS);
Handle<Map> map = initial_map;
map = expectations.AsElementsKind(map, FAST_ELEMENTS);
for (int i = 0; i < kPropCount; i++) {
map = expectations.AddDataField(map, NONE, from_representation, from_type);
}
CHECK(!map->is_deprecated());
CHECK(map->is_stable());
CHECK(expectations.Check(*map));
// Create another branch in transition tree (property at index |kDiffProp|
// has different representatio/field type), initialize expectations.
const int kDiffProp = kPropCount / 2;
Expectations expectations2(isolate, FAST_SMI_ELEMENTS);
Handle<Map> map2 = initial_map;
for (int i = 0; i < kPropCount; i++) {
if (i == kDiffProp) {
map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type);
} else {
map2 = expectations2.AddDataField(map2, NONE, from_representation,
from_type);
}
}
CHECK(!map2->is_deprecated());
CHECK(map2->is_stable());
CHECK(expectations2.Check(*map2));
Zone zone;
Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate);
CompilationInfo info("testing", isolate, &zone);
CHECK(!info.dependencies()->HasAborted());
info.dependencies()->AssumeFieldType(field_owner);
// Reconfigure elements kinds of |map2|, which should generalize
// representations in |map|.
Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS);
// |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));
// |map| should be deprecated and |new_map| should match new expectations.
expectations.SetDataField(kDiffProp, expected_representation, expected_type);
CHECK(map->is_deprecated());
CHECK(!info.dependencies()->HasAborted());
info.dependencies()->Rollback(); // Properly cleanup compilation info.
CHECK_NE(*map, *new_map);
CHECK(!new_map->is_deprecated());
CHECK(expectations.Check(*new_map));
// Update deprecated |map|, it should become |new_map|.
Handle<Map> updated_map = Map::Update(map);
CHECK_EQ(*new_map, *updated_map);
// Ensure Map::FindElementsKindTransitionedMap() is able to find the
// transitioned map.
{
MapHandleList map_list;
map_list.Add(updated_map);
Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list);
CHECK_EQ(*updated_map, transitioned_map);
}
}
// This test ensures that trivial representation/field type generalization
// (from HeapObject to HeapObject) is correctly propagated from one branch of
// transition tree (|map2|) to another (|map|).
//
// + - p0 - p1 - p2A - p3 - p4: |map|
// |
// ek
// |
// {} - p0 - p1 - p2B - p3 - p4: |map2|
//
// where "p2A" and "p2B" differ only in the representation/field type.
//
static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
Representation from_representation, Handle<FieldType> from_type,
Representation to_representation, Handle<FieldType> to_type,
Representation expected_representation, Handle<FieldType> expected_type,
bool expected_field_type_dependency = true) {
Isolate* isolate = CcTest::i_isolate();
Expectations expectations(isolate, FAST_SMI_ELEMENTS);
// Create a map, add required properties to it and initialize expectations.
Handle<Map> initial_map = Map::Create(isolate, 0);
initial_map->set_elements_kind(FAST_SMI_ELEMENTS);
Handle<Map> map = initial_map;
map = expectations.AsElementsKind(map, FAST_ELEMENTS);
for (int i = 0; i < kPropCount; i++) {
map = expectations.AddDataField(map, NONE, from_representation, from_type);
}
CHECK(!map->is_deprecated());
CHECK(map->is_stable());
CHECK(expectations.Check(*map));
// Create another branch in transition tree (property at index |kDiffProp|
// has different attributes), initialize expectations.
const int kDiffProp = kPropCount / 2;
Expectations expectations2(isolate, FAST_SMI_ELEMENTS);
Handle<Map> map2 = initial_map;
for (int i = 0; i < kPropCount; i++) {
if (i == kDiffProp) {
map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type);
} else {
map2 = expectations2.AddDataField(map2, NONE, from_representation,
from_type);
}
}
CHECK(!map2->is_deprecated());
CHECK(map2->is_stable());
CHECK(expectations2.Check(*map2));
Zone zone;
Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate);
CompilationInfo info("testing", isolate, &zone);
CHECK(!info.dependencies()->HasAborted());
info.dependencies()->AssumeFieldType(field_owner);
// Reconfigure elements kinds of |map2|, which should generalize
// representations in |map|.
Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS);
// |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));
// In trivial case |map| should be returned as a result of the elements
// kind reconfiguration, respective field types should be generalized and
// respective code dependencies should be invalidated. |map| should be NOT
// deprecated and it should match new expectations.
expectations.SetDataField(kDiffProp, expected_representation, expected_type);
CHECK(!map->is_deprecated());
CHECK_EQ(*map, *new_map);
CHECK_EQ(expected_field_type_dependency, info.dependencies()->HasAborted());
info.dependencies()->Rollback(); // Properly cleanup compilation info.
CHECK(!new_map->is_deprecated());
CHECK(expectations.Check(*new_map));
Handle<Map> updated_map = Map::Update(map);
CHECK_EQ(*new_map, *updated_map);
// Ensure Map::FindElementsKindTransitionedMap() is able to find the
// transitioned map.
{
MapHandleList map_list;
map_list.Add(updated_map);
Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list);
CHECK_EQ(*updated_map, transitioned_map);
}
}
TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToDouble) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
TestReconfigureElementsKind_GeneralizeRepresentation(
Representation::Smi(), any_type, Representation::Double(), any_type,
Representation::Double(), any_type);
}
TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
TestReconfigureElementsKind_GeneralizeRepresentation(
Representation::Smi(), any_type, Representation::HeapObject(), value_type,
Representation::Tagged(), any_type);
}
TEST(ReconfigureElementsKind_GeneralizeRepresentationDoubleToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
TestReconfigureElementsKind_GeneralizeRepresentation(
Representation::Double(), any_type, Representation::HeapObject(),
value_type, Representation::Tagged(), any_type);
}
TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjToHeapObj) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
Handle<FieldType> current_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
Handle<FieldType> new_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
Handle<FieldType> expected_type = any_type;
TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
Representation::HeapObject(), current_type, Representation::HeapObject(),
new_type, Representation::HeapObject(), expected_type);
current_type = expected_type;
new_type = FieldType::Class(Map::Create(isolate, 0), isolate);
TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
Representation::HeapObject(), any_type, Representation::HeapObject(),
new_type, Representation::HeapObject(), any_type, false);
}
TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjectToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
TestReconfigureElementsKind_GeneralizeRepresentation(
Representation::HeapObject(), value_type, Representation::Smi(), any_type,
Representation::Tagged(), any_type);
}
////////////////////////////////////////////////////////////////////////////////
// A set of tests checking split map deprecation.
//
@ -1640,15 +1925,16 @@ static void TestGeneralizeRepresentationWithSpecialTransition(
CHECK(map->is_stable());
CHECK(expectations.Check(*map));
Expectations expectations2 = expectations;
// Apply some special transition to |map|.
CHECK(map->owns_descriptors());
Handle<Map> map2 = config.Transition(map);
Handle<Map> map2 = config.Transition(map, expectations2);
// |map| should still match expectations.
CHECK(!map->is_deprecated());
CHECK(expectations.Check(*map));
Expectations expectations2 = expectations;
if (config.generalizes_representations()) {
for (int i = 0; i < kPropCount; i++) {
expectations2.GeneralizeRepresentation(i);
@ -1720,13 +2006,15 @@ TEST(ElementsKindTransitionFromMapOwningDescriptor) {
FieldType::Class(Map::Create(isolate, 0), isolate);
struct TestConfig {
Handle<Map> Transition(Handle<Map> map) {
return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS,
INSERT_TRANSITION);
Handle<Map> Transition(Handle<Map> map, Expectations& expectations) {
Handle<Symbol> frozen_symbol(map->GetHeap()->frozen_symbol());
expectations.SetElementsKind(DICTIONARY_ELEMENTS);
return Map::CopyForPreventExtensions(map, NONE, frozen_symbol,
"CopyForPreventExtensions");
}
// TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed.
bool generalizes_representations() const { return false; }
bool is_non_equevalent_transition() const { return false; }
bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
TestGeneralizeRepresentationWithSpecialTransition(
@ -1744,7 +2032,7 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) {
FieldType::Class(Map::Create(isolate, 0), isolate);
struct TestConfig {
Handle<Map> Transition(Handle<Map> map) {
Handle<Map> Transition(Handle<Map> map, Expectations& expectations) {
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
@ -1756,12 +2044,14 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) {
.ToHandleChecked();
CHECK(!map->owns_descriptors());
return Map::CopyAsElementsKind(map, DICTIONARY_ELEMENTS,
INSERT_TRANSITION);
Handle<Symbol> frozen_symbol(map->GetHeap()->frozen_symbol());
expectations.SetElementsKind(DICTIONARY_ELEMENTS);
return Map::CopyForPreventExtensions(map, NONE, frozen_symbol,
"CopyForPreventExtensions");
}
// TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed.
bool generalizes_representations() const { return false; }
bool is_non_equevalent_transition() const { return false; }
bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
TestGeneralizeRepresentationWithSpecialTransition(
@ -1779,7 +2069,7 @@ TEST(ForObservedTransitionFromMapOwningDescriptor) {
FieldType::Class(Map::Create(isolate, 0), isolate);
struct TestConfig {
Handle<Map> Transition(Handle<Map> map) {
Handle<Map> Transition(Handle<Map> map, Expectations& expectations) {
return Map::CopyForObserved(map);
}
// TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed.
@ -1802,7 +2092,7 @@ TEST(ForObservedTransitionFromMapNotOwningDescriptor) {
FieldType::Class(Map::Create(isolate, 0), isolate);
struct TestConfig {
Handle<Map> Transition(Handle<Map> map) {
Handle<Map> Transition(Handle<Map> map, Expectations& expectations) {
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
@ -1845,7 +2135,7 @@ TEST(PrototypeTransitionFromMapOwningDescriptor) {
prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0));
}
Handle<Map> Transition(Handle<Map> map) {
Handle<Map> Transition(Handle<Map> map, Expectations& expectations) {
return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE);
}
// TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed.
@ -1879,7 +2169,7 @@ TEST(PrototypeTransitionFromMapNotOwningDescriptor) {
prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0));
}
Handle<Map> Transition(Handle<Map> map) {
Handle<Map> Transition(Handle<Map> map, Expectations& expectations) {
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);

22
deps/v8/test/cctest/test-strings.cc

@ -1508,3 +1508,25 @@ TEST(FormatMessage) {
"'arg0' returned for property 'arg1' of object 'arg2' is not a function");
CHECK(String::Equals(result, expected));
}
TEST(Regress609831) {
CcTest::InitializeVM();
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
{
HandleScope scope(isolate);
v8::Local<v8::Value> result = CompileRun(
"String.fromCharCode(32, 32, 32, 32, 32, "
"32, 32, 32, 32, 32, 32, 32, 32, 32, 32, "
"32, 32, 32, 32, 32, 32, 32, 32, 32, 32)");
CHECK(v8::Utils::OpenHandle(*result)->IsSeqOneByteString());
}
{
HandleScope scope(isolate);
v8::Local<v8::Value> result = CompileRun(
"String.fromCharCode(432, 432, 432, 432, 432, "
"432, 432, 432, 432, 432, 432, 432, 432, 432, "
"432, 432, 432, 432, 432, 432, 432, 432, 432)");
CHECK(v8::Utils::OpenHandle(*result)->IsSeqTwoByteString());
}
}

18
deps/v8/test/mjsunit/regress/regress-crbug-617524.js

@ -0,0 +1,18 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-gc --always-opt
function f(a,b,c) {
a.a = b;
a[1] = c;
return a;
}
f(new Array(5),.5,0);
var o1 = f(new Array(5),0,.5);
gc();
var o2 = f(new Array(5),0,0);
var o3 = f(new Array(5),0);
assertEquals(0, o3.a);

34
deps/v8/test/mjsunit/regress/regress-seqstrsetchar-ex2.js

@ -1,34 +0,0 @@
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
String.fromCharCode(0xFFF, 0xFFF);
String.fromCharCode(0x7C, 0x7C);
%OptimizeFunctionOnNextCall(String.fromCharCode);
String.fromCharCode(0x7C, 0x7C);
String.fromCharCode(0xFFF, 0xFFF);

61
deps/v8/test/mjsunit/regress/regress-v8-5009.js

@ -0,0 +1,61 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function fn1() {
}
function fn2() {
}
function fn3() {
}
function create(id) {
// Just some `FunctionTemplate` to hang on
var o = new version();
o.id = id;
o[0] = null;
return o;
}
function setM1(o) {
o.m1 = fn1;
}
function setM2(o) {
o.m2 = fn2;
}
function setAltM2(o) {
// Failing StoreIC happens here
o.m2 = fn3;
}
function setAltM1(o) {
o.m1 = null;
}
function test(o) {
o.m2();
o.m1();
}
var p0 = create(0);
var p1 = create(1);
var p2 = create(2);
setM1(p0);
setM1(p1);
setM1(p2);
setM2(p0);
setAltM2(p0);
setAltM1(p0);
setAltM2(p1);
setAltM2(p2);
test(p2);

5
deps/v8/test/mjsunit/string-fromcharcode.js

@ -103,11 +103,6 @@ for (var i = 0; i < 10; i++) {
test(i);
}
assertEquals("AAAA", String.fromCharCode(65, 65, 65, 65));
assertEquals("AAAA", String.fromCharCode(65, 65, 65, 65));
%OptimizeFunctionOnNextCall(String.fromCharCode);
assertEquals("AAAA", String.fromCharCode(65, 65, 65, 65));
// Test the custom IC works correctly when the map changes.
for (var i = 0; i < 10; i++) {
var expected = (i < 5) ? " " : 42;

Loading…
Cancel
Save