Commit 36421dc4 authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[literals] Disable double lazy boilerplate for literals containing Arrays

By creating the boilerplate only on the second instantiation we cannot
propagate back the elements transitions early enough. The resulting literals
would change the initial ElementsKind one step too late and already pollute
ICs that went to monomorphic state.

- Disable lazy AllocationSites for literals containing arrays
- Introduce new ComplexLiteral class to share code between ObjectLiteral
  and ArrayLiteral
- RegexpLiteral now no longer needs a depth_ field

Bug: v8:6517, v8:6519, v8:6211
Change-Id: Ia88d1878954e8895c3d00a7dda8d71e95bba005c
Reviewed-on: https://chromium-review.googlesource.com/563305Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46603}
parent 34874b3b
......@@ -549,10 +549,11 @@ void ObjectLiteral::InitFlagsForPendingNullPrototype(int i) {
}
}
void ObjectLiteral::InitDepthAndFlags() {
if (is_initialized()) return;
int ObjectLiteral::InitDepthAndFlags() {
if (is_initialized()) return depth();
bool is_simple = true;
bool has_seen_prototype = false;
bool needs_initial_allocation_site = false;
int depth_acc = 1;
uint32_t nof_properties = 0;
uint32_t elements = 0;
......@@ -579,10 +580,11 @@ void ObjectLiteral::InitDepthAndFlags() {
}
DCHECK(!property->is_computed_name());
MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
if (m_literal != NULL) {
m_literal->InitDepthAndFlags();
if (m_literal->depth() >= depth_acc) depth_acc = m_literal->depth() + 1;
MaterializedLiteral* literal = property->value()->AsMaterializedLiteral();
if (literal != nullptr) {
int subliteral_depth = literal->InitDepthAndFlags() + 1;
if (subliteral_depth > depth_acc) depth_acc = subliteral_depth;
needs_initial_allocation_site |= literal->NeedsInitialAllocationSite();
}
const AstValue* key = property->key()->AsLiteral()->raw_value();
......@@ -607,11 +609,13 @@ void ObjectLiteral::InitDepthAndFlags() {
nof_properties++;
}
set_depth(depth_acc);
set_is_simple(is_simple);
set_needs_initial_allocation_site(needs_initial_allocation_site);
set_has_elements(elements > 0);
set_fast_elements((max_element_index <= 32) ||
((2 * elements) >= max_element_index));
set_has_elements(elements > 0);
set_is_simple(is_simple);
set_depth(depth_acc);
return depth_acc;
}
void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
......@@ -684,15 +688,14 @@ bool ObjectLiteral::IsFastCloningSupported() const {
// The FastCloneShallowObject builtin doesn't copy elements, and object
// literals don't support copy-on-write (COW) elements for now.
// TODO(mvstanton): make object literals support COW elements.
return fast_elements() && has_shallow_properties() &&
return fast_elements() && is_shallow() &&
properties_count() <=
ConstructorBuiltins::kMaximumClonedShallowObjectProperties;
}
void ArrayLiteral::InitDepthAndFlags() {
int ArrayLiteral::InitDepthAndFlags() {
DCHECK_LT(first_spread_index_, 0);
if (is_initialized()) return;
if (is_initialized()) return depth();
int constants_length = values()->length();
......@@ -703,12 +706,10 @@ void ArrayLiteral::InitDepthAndFlags() {
for (; array_index < constants_length; array_index++) {
Expression* element = values()->at(array_index);
DCHECK(!element->IsSpread());
MaterializedLiteral* m_literal = element->AsMaterializedLiteral();
if (m_literal != NULL) {
m_literal->InitDepthAndFlags();
if (m_literal->depth() + 1 > depth_acc) {
depth_acc = m_literal->depth() + 1;
}
MaterializedLiteral* literal = element->AsMaterializedLiteral();
if (literal != NULL) {
int subliteral_depth = literal->InitDepthAndFlags() + 1;
if (subliteral_depth > depth_acc) depth_acc = subliteral_depth;
}
if (!CompileTimeValue::IsCompileTimeValue(element)) {
......@@ -716,8 +717,12 @@ void ArrayLiteral::InitDepthAndFlags() {
}
}
set_is_simple(is_simple);
set_depth(depth_acc);
set_is_simple(is_simple);
// Array literals always need an initial allocation site to properly track
// elements transitions.
set_needs_initial_allocation_site(true);
return depth_acc;
}
void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
......@@ -813,6 +818,12 @@ void ArrayLiteral::AssignFeedbackSlots(FeedbackVectorSpec* spec,
}
}
bool MaterializedLiteral::IsSimple() const {
if (IsArrayLiteral()) return AsArrayLiteral()->is_simple();
if (IsObjectLiteral()) return AsObjectLiteral()->is_simple();
DCHECK(IsRegExpLiteral());
return false;
}
Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression,
Isolate* isolate) {
......@@ -825,15 +836,22 @@ Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression,
return isolate->factory()->uninitialized_value();
}
void MaterializedLiteral::InitDepthAndFlags() {
int MaterializedLiteral::InitDepthAndFlags() {
if (IsArrayLiteral()) return AsArrayLiteral()->InitDepthAndFlags();
if (IsObjectLiteral()) return AsObjectLiteral()->InitDepthAndFlags();
DCHECK(IsRegExpLiteral());
return 1;
}
bool MaterializedLiteral::NeedsInitialAllocationSite() {
if (IsArrayLiteral()) {
return AsArrayLiteral()->InitDepthAndFlags();
return AsArrayLiteral()->needs_initial_allocation_site();
}
if (IsObjectLiteral()) {
return AsObjectLiteral()->InitDepthAndFlags();
return AsObjectLiteral()->needs_initial_allocation_site();
}
DCHECK(IsRegExpLiteral());
DCHECK_LE(1, depth()); // Depth should be initialized.
return false;
}
void MaterializedLiteral::BuildConstants(Isolate* isolate) {
......
This diff is collapsed.
......@@ -15,8 +15,9 @@ namespace internal {
bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
if (expression->IsLiteral()) return true;
MaterializedLiteral* lit = expression->AsMaterializedLiteral();
return lit != NULL && lit->is_simple();
MaterializedLiteral* literal = expression->AsMaterializedLiteral();
if (literal == nullptr) return false;
return literal->IsSimple();
}
Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
......@@ -33,7 +34,7 @@ Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate,
result->set(kElementsSlot, *object_literal->constant_properties());
} else {
ArrayLiteral* array_literal = expression->AsArrayLiteral();
DCHECK(array_literal != NULL && array_literal->is_simple());
DCHECK(array_literal->is_simple());
result->set(kLiteralTypeSlot, Smi::FromInt(kArrayLiteralFlag));
result->set(kElementsSlot, *array_literal->constant_elements());
}
......
......@@ -541,12 +541,15 @@ void ConstructorBuiltinsAssembler::CreateFastCloneShallowArrayBuiltin(
BIND(&call_runtime);
{
Comment("call runtime");
Node* flags = SmiConstant(ArrayLiteral::kShallowElements |
(allocation_site_mode == TRACK_ALLOCATION_SITE
? 0
: ArrayLiteral::kDisableMementos));
int flags = AggregateLiteral::kIsShallow;
if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
// Force initial allocation sites on the initial literal setup step.
flags |= AggregateLiteral::kNeedsInitialAllocationSite;
} else {
flags |= AggregateLiteral::kDisableMementos;
}
Return(CallRuntime(Runtime::kCreateArrayLiteral, context, closure,
literal_index, constant_elements, flags));
literal_index, constant_elements, SmiConstant(flags)));
}
}
......
......@@ -479,7 +479,7 @@ void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
// Use the FastCloneShallowArray builtin only for shallow boilerplates without
// properties up to the number of elements that the stubs can handle.
if ((p.flags() & ArrayLiteral::kShallowElements) != 0 &&
if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
p.length() < ConstructorBuiltins::kMaximumClonedShallowArrayElements) {
Callable callable = CodeFactory::FastCloneShallowArray(
isolate(), DONT_TRACK_ALLOCATION_SITE);
......@@ -500,7 +500,7 @@ void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
// Use the FastCloneShallowObject builtin only for shallow boilerplates
// without elements up to the number of properties that the stubs can handle.
if ((p.flags() & ObjectLiteral::kShallowProperties) != 0 &&
if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
p.length() <=
ConstructorBuiltins::kMaximumClonedShallowObjectProperties) {
Callable callable =
......
......@@ -18,7 +18,7 @@ namespace interpreter {
uint8_t CreateArrayLiteralFlags::Encode(bool use_fast_shallow_clone,
int runtime_flags) {
uint8_t result = FlagsBits::encode(runtime_flags);
result |= FastShallowCloneBit::encode(use_fast_shallow_clone);
result |= FastCloneSupportedBit::encode(use_fast_shallow_clone);
return result;
}
......
......@@ -18,8 +18,8 @@ namespace interpreter {
class CreateArrayLiteralFlags {
public:
class FlagsBits : public BitField8<int, 0, 4> {};
class FastShallowCloneBit : public BitField8<bool, FlagsBits::kNext, 1> {};
class FlagsBits : public BitField8<int, 0, 5> {};
class FastCloneSupportedBit : public BitField8<bool, FlagsBits::kNext, 1> {};
static uint8_t Encode(bool use_fast_shallow_clone, int runtime_flags);
......@@ -29,7 +29,7 @@ class CreateArrayLiteralFlags {
class CreateObjectLiteralFlags {
public:
class FlagsBits : public BitField8<int, 0, 4> {};
class FlagsBits : public BitField8<int, 0, 5> {};
class FastCloneSupportedBit : public BitField8<bool, FlagsBits::kNext, 1> {};
static uint8_t Encode(int runtime_flags, bool fast_clone_supported);
......
......@@ -2680,9 +2680,9 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) {
Node* bytecode_flags = BytecodeOperandFlag(2);
Label fast_shallow_clone(this), call_runtime(this, Label::kDeferred);
Branch(
IsSetWord32<CreateArrayLiteralFlags::FastShallowCloneBit>(bytecode_flags),
&fast_shallow_clone, &call_runtime);
Branch(IsSetWord32<CreateArrayLiteralFlags::FastCloneSupportedBit>(
bytecode_flags),
&fast_shallow_clone, &call_runtime);
BIND(&fast_shallow_clone);
{
......
......@@ -458,11 +458,8 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index));
CHECK(literals_slot.ToInt() < vector->slot_count());
Handle<Object> literal_site(vector->Get(literals_slot), isolate);
STATIC_ASSERT(static_cast<int>(ObjectLiteral::kShallowProperties) ==
static_cast<int>(ArrayLiteral::kShallowElements));
DeepCopyHints copy_hints =
(flags & ObjectLiteral::kShallowProperties) ? kObjectIsShallow : kNoHints;
(flags & AggregateLiteral::kIsShallow) ? kObjectIsShallow : kNoHints;
if (FLAG_track_double_fields && !FLAG_unbox_double_fields) {
// Make sure we properly clone mutable heap numbers on 32-bit platforms.
copy_hints = kNoHints;
......@@ -475,8 +472,13 @@ MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
site = Handle<AllocationSite>::cast(literal_site);
boilerplate = Handle<JSObject>(site->boilerplate(), isolate);
} else {
// Instantiate a JSArray or JSObject literal from the given {description}.
if (IsUninitializedLiteralSite(literal_site)) {
// Eagerly create AllocationSites for literals that contain an Array.
bool needs_initial_allocation_site =
(flags & AggregateLiteral::kNeedsInitialAllocationSite) != 0;
// TODO(cbruni): Even in the case where we need an initial allocation site
// we could still create the boilerplate lazily to save memory.
if (!needs_initial_allocation_site &&
IsUninitializedLiteralSite(literal_site)) {
PreInitializeLiteralSite(vector, literals_slot);
boilerplate =
Boilerplate::Create(isolate, description, flags, NOT_TENURED);
......
......@@ -14,7 +14,7 @@ parameter count: 1
bytecode array length: 6
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(17),
/* 34 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(37),
/* 51 S> */ B(Return),
]
constant pool: [
......@@ -34,7 +34,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(5), U8(17),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(5), U8(37),
B(Star), R(2),
B(LdaZero),
B(Star), R(1),
......@@ -63,7 +63,7 @@ parameter count: 1
bytecode array length: 6
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateArrayLiteral), U8(0), U8(6), U8(0),
/* 34 S> */ B(CreateArrayLiteral), U8(0), U8(6), U8(4),
/* 62 S> */ B(Return),
]
constant pool: [
......@@ -83,11 +83,11 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(11), U8(0),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(11), U8(4),
B(Star), R(2),
B(LdaZero),
B(Star), R(1),
B(CreateArrayLiteral), U8(1), U8(4), U8(17),
B(CreateArrayLiteral), U8(1), U8(4), U8(37),
B(Star), R(4),
B(LdaZero),
B(Star), R(3),
......@@ -97,7 +97,7 @@ bytecodes: [
B(StaKeyedPropertySloppy), R(2), R(1), U8(12),
B(LdaSmi), I8(1),
B(Star), R(1),
B(CreateArrayLiteral), U8(2), U8(8), U8(17),
B(CreateArrayLiteral), U8(2), U8(8), U8(37),
B(Star), R(4),
B(LdaZero),
B(Star), R(3),
......
......@@ -783,7 +783,7 @@ bytecodes: [
B(Star), R(0),
/* 2591 S> */ B(LdaConstant), U8(255),
B(Star), R(0),
/* 2601 S> */ B(Wide), B(CreateArrayLiteral), U16(256), U16(4), U8(17),
/* 2601 S> */ B(Wide), B(CreateArrayLiteral), U16(256), U16(4), U8(37),
/* 2619 S> */ B(Return),
]
constant pool: [
......
......@@ -327,7 +327,7 @@ bytecodes: [
B(Star), R(6),
B(Mov), R(context), R(18),
B(Mov), R(context), R(19),
/* 36 S> */ B(CreateArrayLiteral), U8(4), U8(4), U8(17),
/* 36 S> */ B(CreateArrayLiteral), U8(4), U8(4), U8(37),
B(Star), R(20),
B(LdaNamedProperty), R(20), U8(5), U8(5),
B(Star), R(21),
......
......@@ -18,7 +18,7 @@ bytecodes: [
B(Star), R(1),
/* 39 E> */ B(LdaNamedProperty), R(1), U8(1), U8(8),
B(Star), R(0),
B(CreateArrayLiteral), U8(2), U8(10), U8(17),
B(CreateArrayLiteral), U8(2), U8(10), U8(37),
B(Star), R(2),
/* 39 E> */ B(CallWithSpread), R(0), R(1), U8(2),
B(LdaUndefined),
......@@ -47,7 +47,7 @@ bytecodes: [
B(Star), R(0),
B(LdaZero),
B(Star), R(2),
B(CreateArrayLiteral), U8(2), U8(10), U8(17),
B(CreateArrayLiteral), U8(2), U8(10), U8(37),
B(Star), R(3),
/* 39 E> */ B(CallWithSpread), R(0), R(1), U8(3),
B(LdaUndefined),
......@@ -78,15 +78,15 @@ bytecodes: [
B(Star), R(2),
B(LdaUndefined),
B(Star), R(4),
B(CreateArrayLiteral), U8(2), U8(8), U8(17),
B(CreateArrayLiteral), U8(2), U8(8), U8(37),
B(Star), R(5),
B(LdaUndefined),
B(Star), R(6),
B(CreateArrayLiteral), U8(3), U8(9), U8(17),
B(CreateArrayLiteral), U8(3), U8(9), U8(37),
B(Star), R(7),
B(CallJSRuntime), U8(%spread_iterable), R(6), U8(2),
B(Star), R(6),
B(CreateArrayLiteral), U8(4), U8(10), U8(17),
B(CreateArrayLiteral), U8(4), U8(10), U8(37),
B(Star), R(7),
B(CallJSRuntime), U8(%spread_arguments), R(4), U8(4),
B(Star), R(4),
......
......@@ -77,7 +77,7 @@ bytecodes: [
/* 10 E> */ B(StackCheck),
/* 15 S> */ B(LdaUndefined),
B(Star), R(0),
B(CreateArrayLiteral), U8(0), U8(4), U8(17),
B(CreateArrayLiteral), U8(0), U8(4), U8(37),
B(Star), R(1),
B(CallJSRuntime), U8(%spread_iterable), R(0), U8(2),
/* 44 S> */ B(Return),
......
......@@ -56,7 +56,7 @@ parameter count: 1
bytecode array length: 22
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(Mov), R(1), R(0),
/* 54 S> */ B(LdaNamedProperty), R(1), U8(1), U8(5),
B(MulSmi), I8(2), U8(7),
......@@ -80,7 +80,7 @@ parameter count: 1
bytecode array length: 25
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(Mov), R(1), R(0),
/* 52 S> */ B(LdaSmi), I8(1),
B(Star), R(2),
......
......@@ -100,7 +100,7 @@ parameter count: 1
bytecode array length: 27
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(Mov), R(1), R(0),
/* 54 S> */ B(LdaNamedProperty), R(1), U8(1), U8(5),
B(ToNumber), R(2), U8(9),
......@@ -126,7 +126,7 @@ parameter count: 1
bytecode array length: 20
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(Mov), R(1), R(0),
/* 54 S> */ B(LdaNamedProperty), R(1), U8(1), U8(5),
B(Dec), U8(9),
......@@ -151,7 +151,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 60 S> */ B(CreateObjectLiteral), U8(1), U8(4), U8(21), R(2),
/* 60 S> */ B(CreateObjectLiteral), U8(1), U8(4), U8(41), R(2),
B(Mov), R(2), R(1),
/* 72 S> */ B(Ldar), R(0),
/* 81 E> */ B(LdaKeyedProperty), R(2), U8(5),
......@@ -180,7 +180,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 60 S> */ B(CreateObjectLiteral), U8(1), U8(4), U8(21), R(2),
/* 60 S> */ B(CreateObjectLiteral), U8(1), U8(4), U8(41), R(2),
B(Mov), R(2), R(1),
/* 72 S> */ B(Ldar), R(0),
/* 83 E> */ B(LdaKeyedProperty), R(2), U8(5),
......@@ -261,7 +261,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 44 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 55 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(17),
/* 55 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(37),
B(Star), R(1),
/* 63 S> */ B(Ldar), R(0),
B(ToNumber), R(3), U8(5),
......
......@@ -14,7 +14,7 @@ parameter count: 1
bytecode array length: 14
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(Mov), R(1), R(0),
/* 56 S> */ B(LdaConstant), U8(1),
B(DeletePropertySloppy), R(1),
......@@ -36,7 +36,7 @@ parameter count: 1
bytecode array length: 14
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 56 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 56 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(Mov), R(1), R(0),
/* 70 S> */ B(LdaConstant), U8(1),
B(DeletePropertyStrict), R(1),
......@@ -58,7 +58,7 @@ parameter count: 1
bytecode array length: 14
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(Mov), R(1), R(0),
/* 56 S> */ B(LdaSmi), I8(2),
B(DeletePropertySloppy), R(1),
......@@ -103,7 +103,7 @@ bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 56 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 56 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(Ldar), R(1),
/* 56 E> */ B(StaCurrentContextSlot), U8(4),
/* 64 S> */ B(CreateClosure), U8(1), U8(5), U8(2),
......
......@@ -47,7 +47,7 @@ bytecodes: [
B(Star), R(6),
B(Mov), R(context), R(19),
B(Mov), R(context), R(20),
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(4), U8(17),
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(4), U8(37),
B(Star), R(21),
B(LdaNamedProperty), R(21), U8(4), U8(9),
B(JumpIfUndefined), U8(17),
......@@ -378,7 +378,7 @@ bytecodes: [
B(Star), R(6),
B(Mov), R(context), R(19),
B(Mov), R(context), R(20),
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(4), U8(17),
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(4), U8(37),
B(Star), R(21),
B(LdaNamedProperty), R(21), U8(4), U8(9),
B(JumpIfUndefined), U8(17),
......@@ -726,7 +726,7 @@ bytecodes: [
B(Star), R(6),
B(Mov), R(context), R(19),
B(Mov), R(context), R(20),
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(4), U8(17),
/* 43 S> */ B(CreateArrayLiteral), U8(3), U8(4), U8(37),
B(Star), R(21),
B(LdaNamedProperty), R(21), U8(4), U8(9),
B(JumpIfUndefined), U8(17),
......@@ -1044,13 +1044,13 @@ bytecodes: [
B(Star), R(8),
B(Mov), R(context), R(11),
B(Mov), R(context), R(12),
/* 31 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(13),
/* 31 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(13),
B(Mov), R(13), R(1),
B(LdaZero),
B(Star), R(4),
B(Mov), R(context), R(15),
B(Mov), R(context), R(16),
/* 68 S> */ B(CreateArrayLiteral), U8(1), U8(5), U8(17),
/* 68 S> */ B(CreateArrayLiteral), U8(1), U8(5), U8(37),
B(Star), R(17),
B(LdaNamedProperty), R(17), U8(2), U8(6),
B(Star), R(18),
......
......@@ -107,7 +107,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
/* 59 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(17),
/* 59 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(37),
B(JumpIfUndefined), U8(46),
B(JumpIfNull), U8(44),
B(ToObject), R(3),
......@@ -150,9 +150,9 @@ parameter count: 1
bytecode array length: 87
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(Mov), R(1), R(0),
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(5), U8(17),
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(5), U8(37),
B(JumpIfUndefined), U8(72),
B(JumpIfNull), U8(70),
B(ToObject), R(1),
......@@ -205,9 +205,9 @@ parameter count: 1
bytecode array length: 62
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(17),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(37),
B(Star), R(0),
/* 72 S> */ B(CreateArrayLiteral), U8(1), U8(5), U8(17),
/* 72 S> */ B(CreateArrayLiteral), U8(1), U8(5), U8(37),
B(JumpIfUndefined), U8(49),
B(JumpIfNull), U8(47),
B(ToObject), R(1),
......
......@@ -18,7 +18,7 @@ bytecodes: [
B(Star), R(4),
B(Mov), R(context), R(10),
B(Mov), R(context), R(11),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(17),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(37),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(1), U8(5),
B(Star), R(13),
......@@ -302,7 +302,7 @@ bytecodes: [
B(Star), R(4),
B(Mov), R(context), R(10),
B(Mov), R(context), R(11),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(17),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(4), U8(37),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(1), U8(5),
B(Star), R(13),
......@@ -444,13 +444,13 @@ parameter count: 1
bytecode array length: 281
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(7),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(7),
B(Mov), R(7), R(0),
B(LdaZero),
B(Star), R(3),
B(Mov), R(context), R(9),
B(Mov), R(context), R(10),
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(5), U8(17),
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(5), U8(37),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(2), U8(6),
B(Star), R(12),
......
......@@ -17,7 +17,7 @@ parameter count: 1
bytecode array length: 25
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(2),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(2),
B(Mov), R(2), R(0),
/* 63 S> */ B(LdaSmi), I8(10),
B(Star), R(1),
......@@ -47,7 +47,7 @@ parameter count: 1
bytecode array length: 25
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(2),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(2),
B(Mov), R(2), R(0),
/* 63 S> */ B(LdaSmi), I8(10),
B(Star), R(1),
......@@ -77,7 +77,7 @@ parameter count: 1
bytecode array length: 25
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(2),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(2),
B(Mov), R(2), R(0),
/* 63 S> */ B(LdaSmi), I8(10),
B(Star), R(1),
......@@ -107,7 +107,7 @@ parameter count: 1
bytecode array length: 25
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(2),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(2),
B(Mov), R(2), R(0),
/* 63 S> */ B(LdaSmi), I8(10),
B(Star), R(1),
......@@ -137,7 +137,7 @@ parameter count: 1
bytecode array length: 24
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(2),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(2),
B(Mov), R(2), R(0),
/* 63 S> */ B(LdaSmi), I8(10),
B(Star), R(1),
......@@ -166,7 +166,7 @@ parameter count: 1
bytecode array length: 24
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(2),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(2),
B(Mov), R(2), R(0),
/* 63 S> */ B(LdaSmi), I8(10),
B(Star), R(1),
......@@ -195,7 +195,7 @@ parameter count: 1
bytecode array length: 24
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(2),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(2),
B(Mov), R(2), R(0),
/* 63 S> */ B(LdaSmi), I8(10),
B(Star), R(1),
......@@ -224,7 +224,7 @@ parameter count: 1
bytecode array length: 24
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(2),
/* 46 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(2),
B(Mov), R(2), R(0),
/* 63 S> */ B(LdaSmi), I8(10),
B(Star), R(1),
......
......@@ -187,7 +187,7 @@ bytecodes: [
B(Star), R(6),
B(Mov), R(context), R(14),
B(Mov), R(context), R(15),
/* 30 S> */ B(CreateArrayLiteral), U8(4), U8(4), U8(17),
/* 30 S> */ B(CreateArrayLiteral), U8(4), U8(4), U8(37),
B(Star), R(16),
B(LdaNamedProperty), R(16), U8(5), U8(5),
B(Star), R(17),
......
......@@ -30,7 +30,7 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kToFastProperties), R(2), U8(1),
B(Star), R(0),
B(Star), R(1),
/* 89 S> */ B(CreateArrayLiteral), U8(1), U8(7), U8(17),
/* 89 S> */ B(CreateArrayLiteral), U8(1), U8(7), U8(37),
B(Star), R(3),
B(Ldar), R(1),
/* 89 E> */ B(ConstructWithSpread), R(1), R(3), U8(1),
......@@ -71,7 +71,7 @@ bytecodes: [
B(Star), R(1),
/* 89 S> */ B(LdaZero),
B(Star), R(3),
B(CreateArrayLiteral), U8(1), U8(7), U8(17),
B(CreateArrayLiteral), U8(1), U8(7), U8(37),
B(Star), R(4),
B(Ldar), R(1),
/* 89 E> */ B(ConstructWithSpread), R(1), R(3), U8(2),
......@@ -114,15 +114,15 @@ bytecodes: [
B(Star), R(2),
B(LdaUndefined),
B(Star), R(4),
/* 93 E> */ B(CreateArrayLiteral), U8(1), U8(5), U8(17),
/* 93 E> */ B(CreateArrayLiteral), U8(1), U8(5), U8(37),
B(Star), R(5),
B(LdaUndefined),
B(Star), R(6),
B(CreateArrayLiteral), U8(2), U8(6), U8(17),
B(CreateArrayLiteral), U8(2), U8(6), U8(37),
B(Star), R(7),
B(CallJSRuntime), U8(%spread_iterable), R(6), U8(2),
B(Star), R(6),
B(CreateArrayLiteral), U8(3), U8(7), U8(17),
B(CreateArrayLiteral), U8(3), U8(7), U8(37),
B(Star), R(7),
B(CallJSRuntime), U8(%spread_arguments), R(4), U8(4),
B(Star), R(4),
......
......@@ -14,7 +14,7 @@ parameter count: 1
bytecode array length: 9
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(0),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(0),
B(Ldar), R(0),
/* 46 S> */ B(Return),
]
......@@ -33,7 +33,7 @@ parameter count: 1
bytecode array length: 9
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(0),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(0),
B(Ldar), R(0),
/* 71 S> */ B(Return),
]
......@@ -54,7 +54,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
/* 75 E> */ B(StaNamedOwnProperty), R(1), U8(1), U8(5),
B(Ldar), R(1),
/* 80 S> */ B(Return),
......@@ -77,7 +77,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(21), R(1),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(41), R(1),
/* 69 E> */ B(AddSmi), I8(1), U8(4),
B(StaNamedOwnProperty), R(1), U8(1), U8(6),
B(Ldar), R(1),
......@@ -99,7 +99,7 @@ parameter count: 1
bytecode array length: 17
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(21), R(0),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(41), R(0),
B(CreateClosure), U8(1), U8(4), U8(2),
B(StaNamedOwnProperty), R(0), U8(2), U8(6),
B(Ldar), R(0),
......@@ -122,7 +122,7 @@ parameter count: 1
bytecode array length: 17
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(21), R(0),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(41), R(0),
B(CreateClosure), U8(1), U8(4), U8(2),
B(StaNamedOwnProperty), R(0), U8(2), U8(6),
B(Ldar), R(0),
......@@ -145,7 +145,7 @@ parameter count: 1
bytecode array length: 33
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(21), R(0),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(41), R(0),
B(LdaConstant), U8(1),
B(Star), R(2),
B(CreateClosure), U8(2), U8(4), U8(2),
......@@ -176,7 +176,7 @@ parameter count: 1
bytecode array length: 36
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(6), U8(21), R(0),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(6), U8(41), R(0),
B(LdaConstant), U8(1),
B(Star), R(2),
B(CreateClosure), U8(2), U8(4), U8(2),
......@@ -208,7 +208,7 @@ parameter count: 1
bytecode array length: 33
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(21), R(0),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(5), U8(41), R(0),
B(LdaConstant), U8(1),
B(Star), R(2),
B(LdaNull),
......@@ -241,7 +241,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(1),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(1),
B(LdaSmi), I8(1),
B(Star), R(3),
B(LdaZero),
......@@ -267,7 +267,7 @@ parameter count: 1
bytecode array length: 9
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(29), R(0),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(57), R(0),
B(Ldar), R(0),
/* 62 S> */ B(Return),
]
......@@ -288,7 +288,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(4), U8(21), R(1),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(4), U8(41), R(1),
/* 60 E> */ B(ToName), R(2),
B(LdaSmi), I8(1),
B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(5),
......@@ -313,7 +313,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(4), U8(21), R(1),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(4), U8(41), R(1),
/* 64 E> */ B(StaNamedOwnProperty), R(1), U8(2), U8(5),
/* 68 E> */ B(ToName), R(2),
B(LdaSmi), I8(1),
......@@ -340,11 +340,11 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(5), U8(21), R(1),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(5), U8(41), R(1),
/* 60 E> */ B(ToName), R(2),
B(LdaSmi), I8(1),
B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(6),
B(CreateObjectLiteral), U8(1), U8(4), U8(21), R(4),
B(CreateObjectLiteral), U8(1), U8(4), U8(41), R(4),
B(Mov), R(1), R(2),
B(Mov), R(4), R(3),
B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(2), U8(2),
......@@ -369,7 +369,7 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(6), U8(21), R(1),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(6), U8(41), R(1),
/* 60 E> */ B(ToName), R(2),
B(LdaConstant), U8(2),
B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(7),
......
......@@ -783,7 +783,7 @@ bytecodes: [
B(Star), R(0),
/* 2591 S> */ B(LdaConstant), U8(255),
B(Star), R(0),
/* 2601 S> */ B(Wide), B(CreateObjectLiteral), U16(256), U16(4), U8(21), R16(1),
/* 2601 S> */ B(Wide), B(CreateObjectLiteral), U16(256), U16(4), U8(41), R16(1),
B(Ldar), R(1),
/* 2638 S> */ B(Return),
]
......
......@@ -225,7 +225,7 @@ parameter count: 1
bytecode array length: 68
bytecodes: [
/* 10 E> */ B(StackCheck),
B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(4),
B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(4),
B(Mov), R(4), R(3),
B(Ldar), R(3),
B(JumpIfUndefined), U8(6),
......
......@@ -112,14 +112,14 @@ bytecodes: [
B(Star), R(5),
B(LdaUndefined),
B(Star), R(6),
B(CreateArrayLiteral), U8(0), U8(4), U8(17),
B(CreateArrayLiteral), U8(0), U8(4), U8(37),
B(Star), R(7),
B(LdaUndefined),
B(Star), R(8),
B(Mov), R(2), R(9),
/* 152 E> */ B(CallJSRuntime), U8(%spread_iterable), R(8), U8(2),
B(Star), R(8),
B(CreateArrayLiteral), U8(1), U8(5), U8(17),
B(CreateArrayLiteral), U8(1), U8(5), U8(37),
B(Star), R(9),
B(CallJSRuntime), U8(%spread_arguments), R(6), U8(4),
B(Star), R(6),
......
......@@ -21,7 +21,7 @@ bytecodes: [
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kDeclareGlobalsForInterpreter), R(1), U8(3),
/* 0 E> */ B(StackCheck),
/* 8 S> */ B(CreateObjectLiteral), U8(1), U8(7), U8(21), R(1),
/* 8 S> */ B(CreateObjectLiteral), U8(1), U8(7), U8(41), R(1),
B(CreateClosure), U8(2), U8(6), U8(0),
B(StaNamedOwnProperty), R(1), U8(3), U8(8),
B(Ldar), R(1),
......
......@@ -14,7 +14,7 @@ parameter count: 1
bytecode array length: 20
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(21), R(0),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(4), U8(41), R(0),
B(Ldar), R(0),
B(ToObject), R(0),
B(Ldar), R(closure),
......
......@@ -165,12 +165,6 @@ function fastliteralcase_smiholey(index, value) {
obj = fastliteralcase_smiholey(5, 1);
assertKind(elements_kind.fast_smi_only, obj);
assertHoley(obj);
// We only start tracking tranistion with the second instantiation.
obj = fastliteralcase_smiholey(5, 1);
assertKind(elements_kind.fast_smi_only, obj);
assertHoley(obj);
obj = fastliteralcase_smiholey(0, 1);
assertKind(elements_kind.fast_smi_only, obj);
assertHoley(obj);
......@@ -268,70 +262,27 @@ assertKind(elements_kind.fast, obj);
// Case: array constructor calls with out of date feedback.
// The boilerplate should incorporate all feedback, but the input array
// should be minimally transitioned based on immediate need.
(function TestLiteralTransition() {
function literal() {
return [1, 2, 3];
(function() {
function foo(i) {
// We have two cases, one for literals one for constructed arrays.
var a = (i == 0)
? [1, 2, 3]
: new Array(1, 2, 3);
return a;
}
var a = literal(); // No boilerplate created yet.
var b = literal(); // Created boilerplate here.
var c = literal(); // Created copy from boilerplate.
// Boilerplate goes holey smi.
b[5] = 1;
assertKind(elements_kind.fast_smi_only, a);
assertKind(elements_kind.fast_smi_only, b);
assertKind(elements_kind.fast_smi_only, c);
assertHoley(literal());
// {a} has been created before tracking was active and thus doesn't affect
// the boilerplate.
a[0] = 3.5;
assertKind(elements_kind.fast_double, a);
assertNotHoley(a);
// Check that modifying {a} didn't change the boilerplate.
var d = literal();
assertKind(elements_kind.fast_smi_only, d);
assertHoley(d);
// Boilerplate goes from holey smi to holey double
c[0] = 3.5;
assertKind(elements_kind.fast_double, c);
assertNotHoley(c);
var e = literal();
assertKind(elements_kind.fast_double, e);
assertHoley(e);
})();
(function TestConstructedArrayTransition() {
// Allocation site tracking is on from the first instantiation for constructor
// calls.
function array() {
return new Array(1, 2, 3);
for (var i = 0; i < 2; i++) {
a = foo(i);
b = foo(i);
b[5] = 1; // boilerplate goes holey
assertHoley(foo(i));
a[0] = 3.5; // boilerplate goes holey double
assertKind(elements_kind.fast_double, a);
assertNotHoley(a);
var c = foo(i);
assertKind(elements_kind.fast_double, c);
assertHoley(c);
}
var a = array();
var b = array();
// Transition kind goes to smi holey.
b[5] = 1;
assertKind(elements_kind.fast_smi_only, a);
assertNotHoley(a);
assertHoley(b);
assertKind(elements_kind.fast_smi_only, b);
assertHoley(array());
// Confirm that modifying {b} did change the transition kind.
var d = array();
assertKind(elements_kind.fast_smi_only, d);
assertHoley(d);
// Sets the transition kind to double.
a[0] = 3.5;
assertKind(elements_kind.fast_double, a);
assertNotHoley(a);
// Confirm that we get the general kind holey + double.
var e = array();
assertKind(elements_kind.fast_double, e);
assertHoley(e);
})();
function newarraycase_onearg(len, value) {
......@@ -424,35 +375,15 @@ gc();
return literal;
}
var obj = get_nested_literal();
assertKind(elements_kind.fast, obj);
assertKind(elements_kind.fast_smi_only, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast_smi_only, obj[2]);
obj[0][0] = 3.5;
obj[2][0] = "hello";
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast, obj[2]);
// We start tracking the allocation site from the second instantiation on.
obj = get_nested_literal();
assertKind(elements_kind.fast, obj);
assertKind(elements_kind.fast_smi_only, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast_smi_only, obj[2]);
obj[0][0] = 3.5;
obj[2][0] = "hello";
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast, obj[2]);
obj = get_nested_literal();
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast, obj[2]);
// A more complex nested literal case.
function get_deep_nested_literal() {
var literal = [[1], [[2], "hello"], 3, [4]];
......@@ -460,15 +391,6 @@ gc();
}
obj = get_deep_nested_literal();
assertKind(elements_kind.fast_smi_only, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1][0]);
obj[0][0] = 3.5;
obj[1][0][0] = "goodbye";
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast, obj[1][0]);
obj = get_deep_nested_literal();
assertKind(elements_kind.fast_smi_only, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1][0]);
obj[0][0] = 3.5;
obj[1][0][0] = "goodbye";
......@@ -500,14 +422,10 @@ gc();
obj = get_object_literal();
assertKind(elements_kind.fast_smi_only, obj.array);
// Force double transition.
obj.array[1] = 3.5;
assertKind(elements_kind.fast_double, obj.array);
obj = get_object_literal();
assertKind(elements_kind.fast_smi_only, obj.array);
obj.array[1] = 3.5;
assertKind(elements_kind.fast_double, obj.array);
// Transition information should be fed back to the inner literal.
obj = get_object_literal();
assertKind(elements_kind.fast_double, obj.array);
......@@ -524,13 +442,6 @@ gc();
assertKind(elements_kind.fast_smi_only, obj.array[1]);
obj.array[1][0] = 3.5;
assertKind(elements_kind.fast_double, obj.array[1]);
obj = get_nested_object_literal();
assertKind(elements_kind.fast, obj.array);
assertKind(elements_kind.fast_smi_only, obj.array[1]);
obj.array[1][0] = 3.5;
assertKind(elements_kind.fast_double, obj.array[1]);
obj = get_nested_object_literal();
assertKind(elements_kind.fast_double, obj.array[1]);
......@@ -547,26 +458,8 @@ gc();
obj = get_nested_literal();
assertKind(elements_kind.fast, obj);
assertKind(elements_kind.fast_smi_only, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast_smi_only, obj[2]);
obj[0][0] = 3.5;
obj[2][0] = "hello";
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast, obj[2]);
obj = get_nested_literal();
assertKind(elements_kind.fast, obj);
assertKind(elements_kind.fast_smi_only, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast_smi_only, obj[2]);
obj[0][0] = 3.5;
obj[2][0] = "hello";
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
assertKind(elements_kind.fast, obj[2]);
obj = get_nested_literal();
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1]);
......@@ -579,15 +472,6 @@ gc();
}
obj = get_deep_nested_literal();
assertKind(elements_kind.fast_smi_only, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1][0]);
obj[0][0] = 3.5;
obj[1][0][0] = "goodbye";
assertKind(elements_kind.fast_double, obj[0]);
assertKind(elements_kind.fast, obj[1][0]);
obj = get_deep_nested_literal();
assertKind(elements_kind.fast_smi_only, obj[0]);
assertKind(elements_kind.fast_smi_only, obj[1][0]);
obj[0][0] = 3.5;
obj[1][0][0] = "goodbye";
......
......@@ -99,20 +99,9 @@ assertOptimized(get_literal);
return [a, b, c];
}
var a = bar(1, 2, 3);
assertKind(elements_kind.fast_smi_only, a);
a = bar(1, 2, 3);
a[0] = 3.5;
a[1] = 'hi';
assertKind(elements_kind.fast, a);
// We only start tracking transition information with the second
// instantiation.
var b = bar(1, 2, 3);
assertKind(elements_kind.fast_smi_only, b);
b[0] = 3.5;
b[1] = 'hi';
b = bar(1, 2, 3);
assertKind(elements_kind.fast, b);
var c = bar(1, 2, 3);
assertKind(elements_kind.fast, c);
})();
......@@ -113,15 +113,11 @@
assertEquals(3, l.y.z)
}
f();
f();
f();
f(); f(); f();
%OptimizeFunctionOnNextCall(f);
f();
f();
f(); f();
%OptimizeFunctionOnNextCall(f);
f();
f();
f(); f();
})();
......
......@@ -57,7 +57,8 @@ function testBasicPrototype() {
assertEquals(Object.getPrototypeOf(obj), Object.prototype);
assertEquals(Object.getPrototypeOf(obj.b), Object.prototype);
};
runTest(testBasicPrototype);
testBasicPrototype();
testBasicPrototype();
function testDynamicValue() {
var z = 24;
......@@ -73,9 +74,10 @@ function testDynamicValue() {
assertEquals(24, obj2.b.y);
assertEquals('Zebra', obj2.c);
}
runTest(testDynamicValue);
testDynamicValue();
testDynamicValue();
function testMultipleInstatiations() {
(function testMultipleInstatiations() {
var arr = [];
for (var i = 0; i < 2; i++) {
arr[i] = {
......@@ -88,8 +90,7 @@ function testMultipleInstatiations() {
arr[0].b.x = 2;
assertEquals(2, arr[0].b.x);
assertEquals(12, arr[1].b.x);
}
runTest(testMultipleInstatiations);
})();
function testSparseElements() {
let sa1 = {
......@@ -253,7 +254,8 @@ function TestSimpleElements() {
o[0] = 0;
assertEquals({0:0, 1:"one", 2:"two"}, o);
}
runTest(TestSimpleElements);
TestSimpleElements();
TestSimpleElements();
function TestNumericNames() {
var o = {
......@@ -277,7 +279,8 @@ function TestNumericNames() {
%HeapObjectVerify(o);
assertEquals(['1.2', '1.3'], Object.keys(o));
}
runTest(TestNumericNames);
TestNumericNames();
TestNumericNames();
function TestDictionaryElements() {
let o = {1024: true};
......@@ -298,7 +301,10 @@ function TestDictionaryElements() {
o2[1024] = "test";
assertEquals(["test"], Object.values(o2));
}
runTest(TestDictionaryElements);
TestDictionaryElements();
TestDictionaryElements();
%OptimizeFunctionOnNextCall(TestDictionaryElements);
TestDictionaryElements();
function TestLiteralElementsKind() {
let o = {0:0, 1:1, 2:2};
......@@ -324,7 +330,10 @@ function TestLiteralElementsKind() {
assertTrue(%HasDictionaryElements({0xFFFFFF:true}));
}
runTest(TestLiteralElementsKind);
TestLiteralElementsKind();
TestLiteralElementsKind();
%OptimizeFunctionOnNextCall(TestLiteralElementsKind);
TestLiteralElementsKind();
function TestNonNumberElementValues() {
var o = {
......@@ -379,7 +388,11 @@ function TestNonNumberElementValues() {
%HeapObjectVerify(o4);
assertEquals(['1', '2', '3', '4', 'a', 'b'], Object.keys(o4));
}
runTest(TestNonNumberElementValues);
TestNonNumberElementValues();
TestNonNumberElementValues();
TestNonNumberElementValues();
%OptimizeFunctionOnNextCall(TestNonNumberElementValues);
TestNonNumberElementValues();
function numericGetters() {
......@@ -406,7 +419,8 @@ function numericGetters() {
get 1.30() {}
});
}
runTest(numericGetters);
numericGetters();
numericGetters();
function numericSetters() {
function TestNumericNamesSetter(expectedKeys, object) {
......@@ -432,7 +446,9 @@ function numericSetters() {
set 1.30(_) {; }
});
};
runTest(numericSetters);
numericSetters();
numericSetters();
function TestProxyWithDefinitionInObjectLiteral() {
// Trap for set should not be used if the definition
......@@ -448,12 +464,14 @@ function TestProxyWithDefinitionInObjectLiteral() {
p[prop] = 'my value';
assertEquals(undefined, p[prop]);
var l = new Proxy({[prop]: 'my value'}, handler);
assertEquals('my value', l[prop]);
};
runTest(TestProxyWithDefinitionInObjectLiteral);
TestProxyWithDefinitionInObjectLiteral();
TestProxyWithDefinitionInObjectLiteral();
function TestLiteralWithNullProto() {
(function TestLiteralWithNullProto() {
// Assume dictionary usage for simple null prototype literal objects,
// this is equivalent to Object.create(null). Note that on the first call
// the literal boilerplate is initialized, and from then on we use a the
......@@ -480,8 +498,7 @@ function TestLiteralWithNullProto() {
testDictModeNullProtoLiteral(() => ({a:1, b:2, __proto__:null}));
testDictModeNullProtoLiteral(() => ({["a"]: 1, __proto__: null}));
testDictModeNullProtoLiteral(() => ({a: Object, __proto__: null}));
}
runTest(TestLiteralWithNullProto);
})();
function testNestedNullProtoLiteral() {
let obj;
......@@ -507,7 +524,8 @@ function testNestedNullProtoLiteral() {
obj.foo.bar = "barValue2";
assertEquals("barValue2", obj.foo.bar);
}
runTest(testNestedNullProtoLiteral);
testNestedNullProtoLiteral();
testNestedNullProtoLiteral();
function TestSlowLiteralOptimized() {
......@@ -531,9 +549,10 @@ function TestSlowLiteralOptimized() {
obj.bar = "barValue2";
assertEquals("barValue2", obj.bar);
};
runTest(TestSlowLiteralOptimized);
TestSlowLiteralOptimized();
TestSlowLiteralOptimized();
function TestLargeDictionaryLiteral() {
(function TestLargeDictionaryLiteral() {
// Create potential large-space object literal.
function createObject() {
// This literal has least kMaxRegularHeapObjectSize / 64 number of
......@@ -1549,8 +1568,7 @@ function TestLargeDictionaryLiteral() {
assertFalse(%HasFastProperties(object2));
assertEquals(Object.getPrototypeOf(object2), null);
assertEquals(keys, Object.keys(object2));
}
runTest(TestLargeDictionaryLiteral);
})();
(function TestPrototypeInObjectLiteral() {
......@@ -1574,21 +1592,3 @@ runTest(TestLargeDictionaryLiteral);
delete Object.prototype.c;
})();
(function testNewLiteralObjectSpace() {
// The first-time literals are created they should reside in new-space.
assertTrue(%InNewSpace([]));
assertTrue(%InNewSpace({}));
let result = [ [0], [1], [2], [3]];
assertTrue(%InNewSpace(result));
for (let i = 0; i < result.length; i++) {
assertTrue(%InNewSpace(result[i]));
}
result = {a:{x:{}}, b:{x:{}}, c:{x:{}}};
assertTrue(%InNewSpace(result));
for (let key in result) {
assertTrue(%InNewSpace(result[key]));
assertTrue(%InNewSpace(result[key].x));
}
})();
......@@ -29,12 +29,11 @@ function literals_sharing_test(warmup, optimize) {
function test() {
var warmup = true;
for (var i = 0; i < 3; i++) {
// We only start tracking allocation information with the second
// instantiation.
var warmup = i < 2;
print("iter: " + i + ", warmup: "+ warmup);
literals_sharing_test(warmup, false);
warmup = false;
}
print("iter: " + i + ", opt: true");
literals_sharing_test(warmup, true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment