Commit af677f29 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[ic] EmitElementStore: don't miss when hitting new space limit.

CSA::EmitElementStore used to bail out (IC miss) via
CSA::CheckForCapacityGrow when the capacity hits the new space
limit, causing the store IC to go megamorphic in my example (see
referenced bug). With this CL, we do what TF'ed code does already:
call into Runtime::kGrowArrayElements (in this situation), thus
staying monomorphic.

Here's a contrived test case:

////////////////////////
let x = [];

function bar() {
  for (let i = 0; i < 50000; ++i) x[i] = i;
}

function foo() {
  for (let i = x.length; i < 100e6; ++i) x[i] = i;
}

bar();
foo();
////////////////////////

This took about 4s on my machine, now it takes 3s.

Bug: v8:7447
Change-Id: I7f268fc55835f363d250613ce0357444a663051c
Reviewed-on: https://chromium-review.googlesource.com/918723
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51297}
parent bedff086
......@@ -8005,7 +8005,8 @@ Node* CodeStubAssembler::CheckForCapacityGrow(
KeyedAccessStoreMode store_mode, Node* length, Node* key,
ParameterMode mode, bool is_js_array, Label* bailout) {
VARIABLE(checked_elements, MachineRepresentation::kTagged);
Label grow_case(this), no_grow_case(this), done(this);
Label grow_case(this), no_grow_case(this), done(this),
grow_bailout(this, Label::kDeferred);
Node* condition;
if (IsHoleyOrDictionaryElementsKind(kind)) {
......@@ -8026,11 +8027,24 @@ Node* CodeStubAssembler::CheckForCapacityGrow(
{
Node* new_elements = TryGrowElementsCapacity(
object, elements, kind, key, current_capacity, mode, bailout);
object, elements, kind, key, current_capacity, mode, &grow_bailout);
checked_elements.Bind(new_elements);
Goto(&fits_capacity);
}
BIND(&grow_bailout);
{
Node* tagged_key = mode == SMI_PARAMETERS
? key
: ChangeInt32ToTagged(TruncateWordToWord32(key));
Node* maybe_elements = CallRuntime(
Runtime::kGrowArrayElements, NoContextConstant(), object, tagged_key);
GotoIf(TaggedIsSmi(maybe_elements), bailout);
CSA_ASSERT(this, IsFixedArrayWithKind(maybe_elements, kind));
checked_elements.Bind(maybe_elements);
Goto(&fits_capacity);
}
BIND(&fits_capacity);
if (is_js_array) {
Node* new_length = IntPtrAdd(key, IntPtrOrSmiConstant(1, mode));
......
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