2014-10-20 11:42:56 +00:00
|
|
|
// Copyright 2014 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.
|
|
|
|
|
2022-07-18 10:54:58 +00:00
|
|
|
#include "test/cctest/test-feedback-vector.h"
|
2014-10-20 11:42:56 +00:00
|
|
|
|
2019-05-17 12:13:44 +00:00
|
|
|
#include "src/api/api-inl.h"
|
2019-05-22 07:55:37 +00:00
|
|
|
#include "src/execution/execution.h"
|
2018-04-09 19:11:22 +00:00
|
|
|
#include "src/heap/factory.h"
|
2018-12-13 23:35:14 +00:00
|
|
|
#include "src/objects/feedback-cell-inl.h"
|
2019-05-23 08:51:46 +00:00
|
|
|
#include "src/objects/objects-inl.h"
|
2022-07-18 10:54:58 +00:00
|
|
|
#include "test/cctest/cctest.h"
|
2014-10-20 11:42:56 +00:00
|
|
|
|
2017-08-11 11:22:28 +00:00
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
2014-10-20 11:42:56 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
#define CHECK_SLOT_KIND(helper, index, expected_kind) \
|
|
|
|
CHECK_EQ(expected_kind, helper.vector()->GetKind(helper.slot(index)));
|
2015-09-28 08:23:35 +00:00
|
|
|
|
|
|
|
|
2015-10-26 13:10:08 +00:00
|
|
|
static Handle<JSFunction> GetFunction(const char* name) {
|
|
|
|
v8::MaybeLocal<v8::Value> v8_f = CcTest::global()->Get(
|
2019-06-21 13:32:50 +00:00
|
|
|
CcTest::isolate()->GetCurrentContext(), v8_str(name));
|
2015-10-26 13:10:08 +00:00
|
|
|
Handle<JSFunction> f =
|
|
|
|
Handle<JSFunction>::cast(v8::Utils::OpenHandle(*v8_f.ToLocalChecked()));
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-10-20 11:42:56 +00:00
|
|
|
TEST(VectorStructure) {
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
Factory* factory = isolate->factory();
|
2016-10-17 12:12:30 +00:00
|
|
|
Zone zone(isolate->allocator(), ZONE_NAME);
|
2014-10-20 11:42:56 +00:00
|
|
|
|
2017-02-08 08:33:33 +00:00
|
|
|
Handle<FeedbackVector> vector;
|
2015-10-01 13:48:05 +00:00
|
|
|
|
|
|
|
{
|
2016-07-28 08:04:10 +00:00
|
|
|
FeedbackVectorSpec one_slot(&zone);
|
2017-09-01 10:49:06 +00:00
|
|
|
one_slot.AddForInSlot();
|
2017-02-07 14:05:02 +00:00
|
|
|
vector = NewFeedbackVector(isolate, &one_slot);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(vector);
|
|
|
|
CHECK_EQ(1, helper.slot_count());
|
|
|
|
}
|
2014-10-20 11:42:56 +00:00
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
{
|
2016-07-28 08:04:10 +00:00
|
|
|
FeedbackVectorSpec one_icslot(&zone);
|
2015-10-01 13:48:05 +00:00
|
|
|
one_icslot.AddCallICSlot();
|
2017-02-07 14:05:02 +00:00
|
|
|
vector = NewFeedbackVector(isolate, &one_icslot);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(vector);
|
|
|
|
CHECK_EQ(1, helper.slot_count());
|
|
|
|
}
|
2014-10-20 11:42:56 +00:00
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
{
|
2016-07-28 08:04:10 +00:00
|
|
|
FeedbackVectorSpec spec(&zone);
|
2015-10-01 13:48:05 +00:00
|
|
|
for (int i = 0; i < 3; i++) {
|
2017-09-01 10:49:06 +00:00
|
|
|
spec.AddForInSlot();
|
2015-10-01 13:48:05 +00:00
|
|
|
}
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
|
|
spec.AddCallICSlot();
|
|
|
|
}
|
2017-02-07 14:05:02 +00:00
|
|
|
vector = NewFeedbackVector(isolate, &spec);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(vector);
|
|
|
|
CHECK_EQ(8, helper.slot_count());
|
|
|
|
|
|
|
|
int index = vector->GetIndex(helper.slot(0));
|
|
|
|
|
2015-10-07 10:33:22 +00:00
|
|
|
CHECK_EQ(helper.slot(0), vector->ToSlot(index));
|
2015-10-01 13:48:05 +00:00
|
|
|
|
|
|
|
index = vector->GetIndex(helper.slot(3));
|
2015-10-07 10:33:22 +00:00
|
|
|
CHECK_EQ(helper.slot(3), vector->ToSlot(index));
|
2015-10-01 13:48:05 +00:00
|
|
|
|
|
|
|
index = vector->GetIndex(helper.slot(7));
|
2017-07-27 12:45:00 +00:00
|
|
|
CHECK_EQ(3 + 4 * FeedbackMetadata::GetSlotSize(FeedbackSlotKind::kCall),
|
2017-02-07 15:19:35 +00:00
|
|
|
index);
|
2015-10-07 10:33:22 +00:00
|
|
|
CHECK_EQ(helper.slot(7), vector->ToSlot(index));
|
2015-10-01 13:48:05 +00:00
|
|
|
|
2017-07-27 12:45:00 +00:00
|
|
|
CHECK_EQ(3 + 5 * FeedbackMetadata::GetSlotSize(FeedbackSlotKind::kCall),
|
2017-02-07 15:19:35 +00:00
|
|
|
vector->length());
|
2015-10-01 13:48:05 +00:00
|
|
|
}
|
2017-01-09 15:31:00 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
FeedbackVectorSpec spec(&zone);
|
2017-09-01 10:49:06 +00:00
|
|
|
spec.AddForInSlot();
|
2020-11-03 11:07:53 +00:00
|
|
|
spec.AddCreateClosureSlot();
|
2017-09-01 10:49:06 +00:00
|
|
|
spec.AddForInSlot();
|
2017-02-07 14:05:02 +00:00
|
|
|
vector = NewFeedbackVector(isolate, &spec);
|
2017-01-09 15:31:00 +00:00
|
|
|
FeedbackVectorHelper helper(vector);
|
2019-03-08 14:57:54 +00:00
|
|
|
FeedbackCell cell = *vector->GetClosureFeedbackCell(0);
|
2017-02-06 10:18:05 +00:00
|
|
|
CHECK_EQ(cell.value(), *factory->undefined_value());
|
2017-01-09 15:31:00 +00:00
|
|
|
}
|
2014-10-27 16:34:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// IC slots need an encoding to recognize what is in there.
|
|
|
|
TEST(VectorICMetadata) {
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
2016-10-17 12:12:30 +00:00
|
|
|
Zone zone(isolate->allocator(), ZONE_NAME);
|
2014-10-27 16:34:28 +00:00
|
|
|
|
2016-07-28 08:04:10 +00:00
|
|
|
FeedbackVectorSpec spec(&zone);
|
2014-10-27 16:34:28 +00:00
|
|
|
// Set metadata.
|
2015-10-01 13:48:05 +00:00
|
|
|
for (int i = 0; i < 40; i++) {
|
|
|
|
switch (i % 4) {
|
2015-09-28 11:41:40 +00:00
|
|
|
case 0:
|
2017-09-01 10:49:06 +00:00
|
|
|
spec.AddForInSlot();
|
2015-09-28 11:41:40 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2015-10-01 13:48:05 +00:00
|
|
|
spec.AddCallICSlot();
|
2015-09-28 11:41:40 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2015-10-01 13:48:05 +00:00
|
|
|
spec.AddLoadICSlot();
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
spec.AddKeyedLoadICSlot();
|
2015-09-28 11:41:40 +00:00
|
|
|
break;
|
2014-10-28 16:05:08 +00:00
|
|
|
}
|
2014-10-27 16:34:28 +00:00
|
|
|
}
|
|
|
|
|
2017-02-07 14:05:02 +00:00
|
|
|
Handle<FeedbackVector> vector = NewFeedbackVector(isolate, &spec);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(vector);
|
|
|
|
CHECK_EQ(40, helper.slot_count());
|
2014-11-27 16:36:18 +00:00
|
|
|
|
2014-10-27 16:34:28 +00:00
|
|
|
// Meanwhile set some feedback values and type feedback values to
|
|
|
|
// verify the data structure remains intact.
|
2020-10-27 11:05:30 +00:00
|
|
|
vector->SynchronizedSet(FeedbackSlot(0), MaybeObject::FromObject(*vector));
|
2014-10-27 16:34:28 +00:00
|
|
|
|
2014-11-27 16:36:18 +00:00
|
|
|
// Verify the metadata is correctly set up from the spec.
|
2015-10-01 13:48:05 +00:00
|
|
|
for (int i = 0; i < 40; i++) {
|
2017-02-07 15:19:35 +00:00
|
|
|
FeedbackSlotKind kind = vector->GetKind(helper.slot(i));
|
2015-10-01 13:48:05 +00:00
|
|
|
switch (i % 4) {
|
|
|
|
case 0:
|
2017-09-01 10:49:06 +00:00
|
|
|
CHECK_EQ(FeedbackSlotKind::kForIn, kind);
|
2015-10-01 13:48:05 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_EQ(FeedbackSlotKind::kCall, kind);
|
2015-10-01 13:48:05 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_EQ(FeedbackSlotKind::kLoadProperty, kind);
|
2015-10-01 13:48:05 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_EQ(FeedbackSlotKind::kLoadKeyed, kind);
|
2015-10-01 13:48:05 +00:00
|
|
|
break;
|
2014-10-27 16:34:28 +00:00
|
|
|
}
|
|
|
|
}
|
2014-10-20 11:42:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-10-28 16:05:08 +00:00
|
|
|
TEST(VectorCallICStates) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2014-10-28 16:05:08 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
// Make sure function f has a call that uses a type feedback slot.
|
|
|
|
CompileRun(
|
2019-03-25 15:05:47 +00:00
|
|
|
"function foo() { return 17; };"
|
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2014-10-28 16:05:08 +00:00
|
|
|
"function f(a) { a(); } f(foo);");
|
2015-10-26 13:10:08 +00:00
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
2014-10-28 16:05:08 +00:00
|
|
|
// There should be one IC.
|
2017-02-07 14:05:02 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
2017-02-07 15:19:35 +00:00
|
|
|
FeedbackSlot slot(0);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2014-10-28 16:05:08 +00:00
|
|
|
|
|
|
|
CompileRun("f(function() { return 16; })");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
|
2014-10-28 16:05:08 +00:00
|
|
|
|
2015-02-04 09:46:05 +00:00
|
|
|
// After a collection, state should remain GENERIC.
|
2017-04-26 22:16:41 +00:00
|
|
|
CcTest::CollectAllGarbage();
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
|
2016-07-13 07:58:40 +00:00
|
|
|
}
|
|
|
|
|
Collect receiver to feedback for prototype.apply
When a function is invoked by prototype.apply, it may undergo following transformation in the JSCallReducer:
receiver.apply(this, args) ->
this.receiver(...args) Since the new target (also the receiver of apply()) is not collected to the feedback slot, further speculative optimization on the new target is not available if the new target
is not a heapconstant.
With this CL, the receiver will be collected to the feedback instead of the target if the target is a prototype.apply. It may improve the performance of the following usecase by ~80%.
function reduceArray(func, arr, r) {
for (var i = 0, len = arr.length; i < len; i++) {
r = func.apply(null, r, arr[i]);
}
return r;
}
var a = 0; for (var i = 0; i < 10000000; i++) {
a += reduceArray(Math.imul, [5,6,2,3,7,6,8,3,7,9,2,5,], 1);
}
console.log(a);
This CL also improves the runTime score of JetStream2/richards-wasm by ~45% in default, ~60% with --turbo-inline-js-wasm-calls.
Change-Id: I542eb8d3fcb592f4e0993af93ba1af70e89c3982
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2639813
Commit-Queue: Fanchen Kong <fanchen.kong@intel.com>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74413}
2021-03-25 22:56:46 +00:00
|
|
|
// Test the Call IC states transfer with Function.prototype.apply
|
|
|
|
TEST(VectorCallICStateApply) {
|
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
Collect receiver to feedback for prototype.apply
When a function is invoked by prototype.apply, it may undergo following transformation in the JSCallReducer:
receiver.apply(this, args) ->
this.receiver(...args) Since the new target (also the receiver of apply()) is not collected to the feedback slot, further speculative optimization on the new target is not available if the new target
is not a heapconstant.
With this CL, the receiver will be collected to the feedback instead of the target if the target is a prototype.apply. It may improve the performance of the following usecase by ~80%.
function reduceArray(func, arr, r) {
for (var i = 0, len = arr.length; i < len; i++) {
r = func.apply(null, r, arr[i]);
}
return r;
}
var a = 0; for (var i = 0; i < 10000000; i++) {
a += reduceArray(Math.imul, [5,6,2,3,7,6,8,3,7,9,2,5,], 1);
}
console.log(a);
This CL also improves the runTime score of JetStream2/richards-wasm by ~45% in default, ~60% with --turbo-inline-js-wasm-calls.
Change-Id: I542eb8d3fcb592f4e0993af93ba1af70e89c3982
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2639813
Commit-Queue: Fanchen Kong <fanchen.kong@intel.com>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74413}
2021-03-25 22:56:46 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
|
|
|
|
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
// Make sure function f has a call that uses a type feedback slot.
|
|
|
|
CompileRun(
|
|
|
|
"var F;"
|
|
|
|
"%EnsureFeedbackVectorForFunction(foo);"
|
|
|
|
"function foo() { return F.apply(null, arguments); }"
|
|
|
|
"F = Math.min;"
|
|
|
|
"foo();");
|
|
|
|
Handle<JSFunction> foo = GetFunction("foo");
|
|
|
|
Handle<JSFunction> F = GetFunction("F");
|
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(foo->feedback_vector(), isolate);
|
|
|
|
FeedbackSlot slot(4);
|
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
Collect receiver to feedback for prototype.apply
When a function is invoked by prototype.apply, it may undergo following transformation in the JSCallReducer:
receiver.apply(this, args) ->
this.receiver(...args) Since the new target (also the receiver of apply()) is not collected to the feedback slot, further speculative optimization on the new target is not available if the new target
is not a heapconstant.
With this CL, the receiver will be collected to the feedback instead of the target if the target is a prototype.apply. It may improve the performance of the following usecase by ~80%.
function reduceArray(func, arr, r) {
for (var i = 0, len = arr.length; i < len; i++) {
r = func.apply(null, r, arr[i]);
}
return r;
}
var a = 0; for (var i = 0; i < 10000000; i++) {
a += reduceArray(Math.imul, [5,6,2,3,7,6,8,3,7,9,2,5,], 1);
}
console.log(a);
This CL also improves the runTime score of JetStream2/richards-wasm by ~45% in default, ~60% with --turbo-inline-js-wasm-calls.
Change-Id: I542eb8d3fcb592f4e0993af93ba1af70e89c3982
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2639813
Commit-Queue: Fanchen Kong <fanchen.kong@intel.com>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74413}
2021-03-25 22:56:46 +00:00
|
|
|
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
|
|
|
|
HeapObject heap_object;
|
|
|
|
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
|
|
|
|
CHECK_EQ(*F, heap_object);
|
|
|
|
|
|
|
|
CompileRun(
|
|
|
|
"F = Math.max;"
|
|
|
|
"foo();");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
Collect receiver to feedback for prototype.apply
When a function is invoked by prototype.apply, it may undergo following transformation in the JSCallReducer:
receiver.apply(this, args) ->
this.receiver(...args) Since the new target (also the receiver of apply()) is not collected to the feedback slot, further speculative optimization on the new target is not available if the new target
is not a heapconstant.
With this CL, the receiver will be collected to the feedback instead of the target if the target is a prototype.apply. It may improve the performance of the following usecase by ~80%.
function reduceArray(func, arr, r) {
for (var i = 0, len = arr.length; i < len; i++) {
r = func.apply(null, r, arr[i]);
}
return r;
}
var a = 0; for (var i = 0; i < 10000000; i++) {
a += reduceArray(Math.imul, [5,6,2,3,7,6,8,3,7,9,2,5,], 1);
}
console.log(a);
This CL also improves the runTime score of JetStream2/richards-wasm by ~45% in default, ~60% with --turbo-inline-js-wasm-calls.
Change-Id: I542eb8d3fcb592f4e0993af93ba1af70e89c3982
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2639813
Commit-Queue: Fanchen Kong <fanchen.kong@intel.com>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74413}
2021-03-25 22:56:46 +00:00
|
|
|
CHECK_EQ(CallFeedbackContent::kTarget, nexus.GetCallFeedbackContent());
|
|
|
|
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
|
|
|
|
CHECK_EQ(*isolate->function_prototype_apply(), heap_object);
|
|
|
|
|
|
|
|
CompileRun(
|
|
|
|
"F.apply = (function () { return; });"
|
|
|
|
"foo();");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
|
Collect receiver to feedback for prototype.apply
When a function is invoked by prototype.apply, it may undergo following transformation in the JSCallReducer:
receiver.apply(this, args) ->
this.receiver(...args) Since the new target (also the receiver of apply()) is not collected to the feedback slot, further speculative optimization on the new target is not available if the new target
is not a heapconstant.
With this CL, the receiver will be collected to the feedback instead of the target if the target is a prototype.apply. It may improve the performance of the following usecase by ~80%.
function reduceArray(func, arr, r) {
for (var i = 0, len = arr.length; i < len; i++) {
r = func.apply(null, r, arr[i]);
}
return r;
}
var a = 0; for (var i = 0; i < 10000000; i++) {
a += reduceArray(Math.imul, [5,6,2,3,7,6,8,3,7,9,2,5,], 1);
}
console.log(a);
This CL also improves the runTime score of JetStream2/richards-wasm by ~45% in default, ~60% with --turbo-inline-js-wasm-calls.
Change-Id: I542eb8d3fcb592f4e0993af93ba1af70e89c3982
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2639813
Commit-Queue: Fanchen Kong <fanchen.kong@intel.com>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74413}
2021-03-25 22:56:46 +00:00
|
|
|
}
|
|
|
|
|
2017-08-03 18:30:22 +00:00
|
|
|
TEST(VectorCallFeedback) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2016-07-13 07:58:40 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
// Make sure function f has a call that uses a type feedback slot.
|
|
|
|
CompileRun(
|
|
|
|
"function foo() { return 17; }"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2017-08-03 18:30:22 +00:00
|
|
|
"function f(a) { a(); } f(foo);");
|
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
|
|
|
Handle<JSFunction> foo = GetFunction("foo");
|
|
|
|
// There should be one IC.
|
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
|
|
|
FeedbackSlot slot(0);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2017-08-03 18:30:22 +00:00
|
|
|
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2018-12-20 15:47:47 +00:00
|
|
|
HeapObject heap_object;
|
Reland [in-place weak refs] Fix MaybeObject function names
E.g., "ToWeakHeapObject" was misleading, since it didn't convert to a weak heap
object, instead returned a weakly pointed heap object. Change the function names
(in this case, to "GetHeapObjectIfWeak") to reflect this.
Also make casts explicit, if a MaybeObject is an Object, we can call cast<Object>().
Previous version: https://chromium-review.googlesource.com/1219025
BUG=v8:7308
TBR=ishell@chromium.org, ulan@chromium.org, ahaas@chromium.org, yangguo@chromium.org, tebbi@chromium.org
Change-Id: I503d4a2a3a68f85e9e02e1c2f9fc1c4187c8e9a1
Reviewed-on: https://chromium-review.googlesource.com/1226800
Reviewed-by: Marja Hölttä <marja@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55934}
2018-09-17 07:36:25 +00:00
|
|
|
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
|
2018-05-23 06:53:49 +00:00
|
|
|
CHECK_EQ(*foo, heap_object);
|
2017-08-03 18:30:22 +00:00
|
|
|
|
|
|
|
CcTest::CollectAllGarbage();
|
|
|
|
// It should stay monomorphic even after a GC.
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2017-08-03 18:30:22 +00:00
|
|
|
}
|
|
|
|
|
2020-02-29 08:21:03 +00:00
|
|
|
TEST(VectorPolymorphicCallFeedback) {
|
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2020-02-29 08:21:03 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
|
|
|
FLAG_lazy_feedback_allocation = false;
|
|
|
|
|
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
// Make sure the call feedback of a() in f() becomes polymorphic.
|
|
|
|
CompileRun(
|
|
|
|
"function foo_maker() { return () => { return 17; } }"
|
|
|
|
"a_foo = foo_maker();"
|
|
|
|
"function f(a) { a(); } f(foo_maker());"
|
|
|
|
"f(foo_maker());");
|
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
|
|
|
Handle<JSFunction> a_foo = GetFunction("a_foo");
|
|
|
|
// There should be one IC.
|
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
|
|
|
FeedbackSlot slot(0);
|
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
|
|
|
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
|
2020-02-29 08:21:03 +00:00
|
|
|
HeapObject heap_object;
|
|
|
|
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
|
|
|
|
CHECK(heap_object.IsFeedbackCell(isolate));
|
|
|
|
// Ensure this is the feedback cell for the closure returned by
|
|
|
|
// foo_maker.
|
|
|
|
CHECK_EQ(heap_object, a_foo->raw_feedback_cell());
|
|
|
|
}
|
|
|
|
|
2017-08-03 18:30:22 +00:00
|
|
|
TEST(VectorCallFeedbackForArray) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2017-08-03 18:30:22 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
// Make sure function f has a call that uses a type feedback slot.
|
2019-03-25 15:05:47 +00:00
|
|
|
CompileRun(
|
|
|
|
"function f(a) { a(); };"
|
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
|
|
|
"f(Array);");
|
2016-07-13 07:58:40 +00:00
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
|
|
|
// There should be one IC.
|
2017-02-07 14:05:02 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
2017-02-07 15:19:35 +00:00
|
|
|
FeedbackSlot slot(0);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2014-10-28 16:05:08 +00:00
|
|
|
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2018-12-20 15:47:47 +00:00
|
|
|
HeapObject heap_object;
|
Reland [in-place weak refs] Fix MaybeObject function names
E.g., "ToWeakHeapObject" was misleading, since it didn't convert to a weak heap
object, instead returned a weakly pointed heap object. Change the function names
(in this case, to "GetHeapObjectIfWeak") to reflect this.
Also make casts explicit, if a MaybeObject is an Object, we can call cast<Object>().
Previous version: https://chromium-review.googlesource.com/1219025
BUG=v8:7308
TBR=ishell@chromium.org, ulan@chromium.org, ahaas@chromium.org, yangguo@chromium.org, tebbi@chromium.org
Change-Id: I503d4a2a3a68f85e9e02e1c2f9fc1c4187c8e9a1
Reviewed-on: https://chromium-review.googlesource.com/1226800
Reviewed-by: Marja Hölttä <marja@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55934}
2018-09-17 07:36:25 +00:00
|
|
|
CHECK(nexus.GetFeedback()->GetHeapObjectIfWeak(&heap_object));
|
2018-05-23 06:53:49 +00:00
|
|
|
CHECK_EQ(*isolate->array_function(), heap_object);
|
2014-10-28 16:05:08 +00:00
|
|
|
|
2017-04-26 22:16:41 +00:00
|
|
|
CcTest::CollectAllGarbage();
|
2016-07-13 07:58:40 +00:00
|
|
|
// It should stay monomorphic even after a GC.
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2014-10-28 16:05:08 +00:00
|
|
|
}
|
2014-11-27 16:36:18 +00:00
|
|
|
|
2016-05-24 11:53:13 +00:00
|
|
|
TEST(VectorCallCounts) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2016-05-24 11:53:13 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
|
|
|
|
// Make sure function f has a call that uses a type feedback slot.
|
|
|
|
CompileRun(
|
|
|
|
"function foo() { return 17; }"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2016-05-24 11:53:13 +00:00
|
|
|
"function f(a) { a(); } f(foo);");
|
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
|
|
|
// There should be one IC.
|
2017-02-07 14:05:02 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
2017-02-07 15:19:35 +00:00
|
|
|
FeedbackSlot slot(0);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2016-05-24 11:53:13 +00:00
|
|
|
|
|
|
|
CompileRun("f(foo); f(foo);");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2017-12-08 12:56:58 +00:00
|
|
|
CHECK_EQ(3, nexus.GetCallCount());
|
2016-09-13 11:03:43 +00:00
|
|
|
|
|
|
|
// Send the IC megamorphic, but we should still have incrementing counts.
|
|
|
|
CompileRun("f(function() { return 12; });");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
|
2017-12-08 12:56:58 +00:00
|
|
|
CHECK_EQ(4, nexus.GetCallCount());
|
2016-07-13 07:58:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(VectorConstructCounts) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2016-07-13 07:58:40 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
2016-05-24 11:53:13 +00:00
|
|
|
|
2016-07-13 07:58:40 +00:00
|
|
|
// Make sure function f has a call that uses a type feedback slot.
|
2016-05-24 11:53:13 +00:00
|
|
|
CompileRun(
|
|
|
|
"function Foo() {}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2016-05-24 11:53:13 +00:00
|
|
|
"function f(a) { new a(); } f(Foo);");
|
2016-07-13 07:58:40 +00:00
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
2017-02-07 14:05:02 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
2016-09-14 03:22:56 +00:00
|
|
|
|
2017-02-07 15:19:35 +00:00
|
|
|
FeedbackSlot slot(0);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2016-09-14 03:22:56 +00:00
|
|
|
|
Reland [in-place weak refs] Fix MaybeObject function names
E.g., "ToWeakHeapObject" was misleading, since it didn't convert to a weak heap
object, instead returned a weakly pointed heap object. Change the function names
(in this case, to "GetHeapObjectIfWeak") to reflect this.
Also make casts explicit, if a MaybeObject is an Object, we can call cast<Object>().
Previous version: https://chromium-review.googlesource.com/1219025
BUG=v8:7308
TBR=ishell@chromium.org, ulan@chromium.org, ahaas@chromium.org, yangguo@chromium.org, tebbi@chromium.org
Change-Id: I503d4a2a3a68f85e9e02e1c2f9fc1c4187c8e9a1
Reviewed-on: https://chromium-review.googlesource.com/1226800
Reviewed-by: Marja Hölttä <marja@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55934}
2018-09-17 07:36:25 +00:00
|
|
|
CHECK(feedback_vector->Get(slot)->IsWeak());
|
2016-05-24 11:53:13 +00:00
|
|
|
|
|
|
|
CompileRun("f(Foo); f(Foo);");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2017-12-08 12:56:58 +00:00
|
|
|
CHECK_EQ(3, nexus.GetCallCount());
|
2016-09-14 03:22:56 +00:00
|
|
|
|
|
|
|
// Send the IC megamorphic, but we should still have incrementing counts.
|
|
|
|
CompileRun("f(function() {});");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::GENERIC, nexus.ic_state());
|
2017-12-08 12:56:58 +00:00
|
|
|
CHECK_EQ(4, nexus.GetCallCount());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(VectorSpeculationMode) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2017-12-08 12:56:58 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
|
|
|
|
// Make sure function f has a call that uses a type feedback slot.
|
|
|
|
CompileRun(
|
|
|
|
"function Foo() {}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2017-12-08 12:56:58 +00:00
|
|
|
"function f(a) { new a(); } f(Foo);");
|
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
|
|
|
|
|
|
|
FeedbackSlot slot(0);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2017-12-08 14:07:56 +00:00
|
|
|
CHECK_EQ(SpeculationMode::kAllowSpeculation, nexus.GetSpeculationMode());
|
2017-12-08 12:56:58 +00:00
|
|
|
|
|
|
|
CompileRun("f(Foo); f(Foo);");
|
|
|
|
CHECK_EQ(3, nexus.GetCallCount());
|
2017-12-08 14:07:56 +00:00
|
|
|
CHECK_EQ(SpeculationMode::kAllowSpeculation, nexus.GetSpeculationMode());
|
2017-12-08 12:56:58 +00:00
|
|
|
|
2017-12-08 14:07:56 +00:00
|
|
|
nexus.SetSpeculationMode(SpeculationMode::kDisallowSpeculation);
|
|
|
|
CHECK_EQ(SpeculationMode::kDisallowSpeculation, nexus.GetSpeculationMode());
|
2018-02-12 06:28:08 +00:00
|
|
|
CHECK_EQ(3, nexus.GetCallCount());
|
|
|
|
|
2017-12-08 14:07:56 +00:00
|
|
|
nexus.SetSpeculationMode(SpeculationMode::kAllowSpeculation);
|
|
|
|
CHECK_EQ(SpeculationMode::kAllowSpeculation, nexus.GetSpeculationMode());
|
2018-02-12 06:28:08 +00:00
|
|
|
CHECK_EQ(3, nexus.GetCallCount());
|
2016-05-24 11:53:13 +00:00
|
|
|
}
|
2014-11-27 16:36:18 +00:00
|
|
|
|
2021-05-27 10:58:04 +00:00
|
|
|
TEST(VectorCallSpeculationModeAndFeedbackContent) {
|
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (!i::FLAG_turbofan) return;
|
|
|
|
if (i::FLAG_always_turbofan) return;
|
2021-05-27 10:58:04 +00:00
|
|
|
if (i::FLAG_jitless) return;
|
|
|
|
FLAG_allow_natives_syntax = true;
|
|
|
|
|
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
|
|
|
|
CompileRun(
|
|
|
|
"function min() { return Math.min.apply(null, arguments); }"
|
|
|
|
"function f(x) { return min(x, 0); }"
|
|
|
|
"%PrepareFunctionForOptimization(min);"
|
|
|
|
"%PrepareFunctionForOptimization(f);"
|
|
|
|
"f(1);");
|
|
|
|
Handle<JSFunction> min = GetFunction("min");
|
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(min->feedback_vector(), isolate);
|
|
|
|
FeedbackSlot slot(6);
|
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
|
|
|
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2021-05-27 10:58:04 +00:00
|
|
|
CHECK_EQ(SpeculationMode::kAllowSpeculation, nexus.GetSpeculationMode());
|
|
|
|
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
|
|
|
|
CompileRun("%OptimizeFunctionOnNextCall(f); f(1);");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2021-05-27 10:58:04 +00:00
|
|
|
CHECK_EQ(SpeculationMode::kAllowSpeculation, nexus.GetSpeculationMode());
|
|
|
|
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
|
|
|
|
CompileRun("f({});"); // Deoptimizes.
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2021-05-27 10:58:04 +00:00
|
|
|
CHECK_EQ(SpeculationMode::kDisallowSpeculation, nexus.GetSpeculationMode());
|
|
|
|
CHECK_EQ(CallFeedbackContent::kReceiver, nexus.GetCallFeedbackContent());
|
|
|
|
}
|
|
|
|
|
2014-11-27 16:36:18 +00:00
|
|
|
TEST(VectorLoadICStates) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2014-11-27 16:36:18 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
|
|
|
|
// Make sure function f has a call that uses a type feedback slot.
|
|
|
|
CompileRun(
|
|
|
|
"var o = { foo: 3 };"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2014-11-27 16:36:18 +00:00
|
|
|
"function f(a) { return a.foo; } f(o);");
|
2015-10-26 13:10:08 +00:00
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
2014-11-27 16:36:18 +00:00
|
|
|
// There should be one IC.
|
2017-02-07 14:05:02 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
2017-02-07 15:19:35 +00:00
|
|
|
FeedbackSlot slot(0);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2014-11-27 16:36:18 +00:00
|
|
|
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2014-11-27 16:36:18 +00:00
|
|
|
// Verify that the monomorphic map is the one we expect.
|
2015-10-26 13:10:08 +00:00
|
|
|
v8::MaybeLocal<v8::Value> v8_o =
|
|
|
|
CcTest::global()->Get(context.local(), v8_str("o"));
|
|
|
|
Handle<JSObject> o =
|
|
|
|
Handle<JSObject>::cast(v8::Utils::OpenHandle(*v8_o.ToLocalChecked()));
|
2019-02-12 12:27:10 +00:00
|
|
|
CHECK_EQ(o->map(), nexus.GetFirstMap());
|
2014-11-27 16:36:18 +00:00
|
|
|
|
|
|
|
// Now go polymorphic.
|
|
|
|
CompileRun("f({ blarg: 3, foo: 2 })");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
|
2014-11-27 16:36:18 +00:00
|
|
|
|
|
|
|
CompileRun(
|
|
|
|
"delete o.foo;"
|
|
|
|
"f(o)");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
|
2014-11-27 16:36:18 +00:00
|
|
|
|
|
|
|
CompileRun("f({ blarg: 3, torino: 10, foo: 2 })");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
|
2017-05-09 22:36:00 +00:00
|
|
|
MapHandles maps;
|
2017-04-28 10:43:34 +00:00
|
|
|
nexus.ExtractMaps(&maps);
|
2017-05-09 22:36:00 +00:00
|
|
|
CHECK_EQ(4, maps.size());
|
2014-11-27 16:36:18 +00:00
|
|
|
|
|
|
|
// Finally driven megamorphic.
|
|
|
|
CompileRun("f({ blarg: 3, gran: 3, torino: 10, foo: 2 })");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MEGAMORPHIC, nexus.ic_state());
|
2019-02-12 12:27:10 +00:00
|
|
|
CHECK(nexus.GetFirstMap().is_null());
|
2014-11-27 16:36:18 +00:00
|
|
|
|
2014-12-12 13:56:11 +00:00
|
|
|
// After a collection, state should not be reset to PREMONOMORPHIC.
|
2017-04-26 22:16:41 +00:00
|
|
|
CcTest::CollectAllGarbage();
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MEGAMORPHIC, nexus.ic_state());
|
2014-11-27 16:36:18 +00:00
|
|
|
}
|
2015-01-15 12:52:33 +00:00
|
|
|
|
2017-02-07 09:03:16 +00:00
|
|
|
TEST(VectorLoadGlobalICSlotSharing) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2015-03-12 09:22:47 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
|
2017-02-07 09:03:16 +00:00
|
|
|
// Function f has 5 LoadGlobalICs: 3 for {o} references outside of "typeof"
|
|
|
|
// operator and 2 for {o} references inside "typeof" operator.
|
2015-03-12 09:22:47 +00:00
|
|
|
CompileRun(
|
2015-07-06 16:36:28 +00:00
|
|
|
"o = 10;"
|
2015-03-12 09:22:47 +00:00
|
|
|
"function f() {"
|
2016-08-08 01:15:22 +00:00
|
|
|
" var x = o || 10;"
|
2017-02-07 09:03:16 +00:00
|
|
|
" var y = typeof o;"
|
|
|
|
" return o , typeof o, x , y, o;"
|
2015-03-12 09:22:47 +00:00
|
|
|
"}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2015-03-12 09:22:47 +00:00
|
|
|
"f();");
|
2015-10-26 13:10:08 +00:00
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
2017-02-07 09:03:16 +00:00
|
|
|
// There should be two IC slots for {o} references outside and inside
|
|
|
|
// typeof operator respectively.
|
2017-02-07 14:05:02 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(feedback_vector);
|
2017-02-07 09:03:16 +00:00
|
|
|
CHECK_EQ(2, helper.slot_count());
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
|
|
|
|
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kLoadGlobalInsideTypeof);
|
2017-02-07 15:19:35 +00:00
|
|
|
FeedbackSlot slot1 = helper.slot(0);
|
|
|
|
FeedbackSlot slot2 = helper.slot(1);
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC,
|
|
|
|
FeedbackNexus(feedback_vector, slot1).ic_state());
|
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC,
|
|
|
|
FeedbackNexus(feedback_vector, slot2).ic_state());
|
2015-03-12 09:22:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-15 12:52:33 +00:00
|
|
|
TEST(VectorLoadICOnSmi) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2015-01-15 12:52:33 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
Heap* heap = isolate->heap();
|
|
|
|
|
|
|
|
// Make sure function f has a call that uses a type feedback slot.
|
|
|
|
CompileRun(
|
|
|
|
"var o = { foo: 3 };"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2019-08-05 14:37:22 +00:00
|
|
|
"function f(a) { return a.foo; } f(34);");
|
2015-10-26 13:10:08 +00:00
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
2015-01-15 12:52:33 +00:00
|
|
|
// There should be one IC.
|
2017-02-07 14:05:02 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector =
|
|
|
|
Handle<FeedbackVector>(f->feedback_vector(), isolate);
|
2017-02-07 15:19:35 +00:00
|
|
|
FeedbackSlot slot(0);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2015-01-15 12:52:33 +00:00
|
|
|
// Verify that the monomorphic map is the one we expect.
|
2018-11-13 06:16:42 +00:00
|
|
|
Map number_map = ReadOnlyRoots(heap).heap_number_map();
|
2019-02-12 12:27:10 +00:00
|
|
|
CHECK_EQ(number_map, nexus.GetFirstMap());
|
2015-01-15 12:52:33 +00:00
|
|
|
|
|
|
|
// Now go polymorphic on o.
|
|
|
|
CompileRun("f(o)");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
|
2015-01-15 12:52:33 +00:00
|
|
|
|
2017-05-09 22:36:00 +00:00
|
|
|
MapHandles maps;
|
2017-04-28 10:43:34 +00:00
|
|
|
nexus.ExtractMaps(&maps);
|
2017-05-09 22:36:00 +00:00
|
|
|
CHECK_EQ(2, maps.size());
|
2015-01-15 12:52:33 +00:00
|
|
|
|
|
|
|
// One of the maps should be the o map.
|
2015-10-26 13:10:08 +00:00
|
|
|
v8::MaybeLocal<v8::Value> v8_o =
|
|
|
|
CcTest::global()->Get(context.local(), v8_str("o"));
|
|
|
|
Handle<JSObject> o =
|
|
|
|
Handle<JSObject>::cast(v8::Utils::OpenHandle(*v8_o.ToLocalChecked()));
|
2015-01-15 12:52:33 +00:00
|
|
|
bool number_map_found = false;
|
|
|
|
bool o_map_found = false;
|
2017-05-09 22:36:00 +00:00
|
|
|
for (Handle<Map> current : maps) {
|
2015-01-15 12:52:33 +00:00
|
|
|
if (*current == number_map)
|
|
|
|
number_map_found = true;
|
|
|
|
else if (*current == o->map())
|
|
|
|
o_map_found = true;
|
|
|
|
}
|
|
|
|
CHECK(number_map_found && o_map_found);
|
|
|
|
|
|
|
|
// The degree of polymorphism doesn't change.
|
|
|
|
CompileRun("f(100)");
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::POLYMORPHIC, nexus.ic_state());
|
2017-05-09 22:36:00 +00:00
|
|
|
MapHandles maps2;
|
2017-04-28 10:43:34 +00:00
|
|
|
nexus.ExtractMaps(&maps2);
|
2017-05-09 22:36:00 +00:00
|
|
|
CHECK_EQ(2, maps2.size());
|
2015-01-15 12:52:33 +00:00
|
|
|
}
|
2015-07-30 10:37:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
TEST(ReferenceContextAllocatesNoSlots) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2018-10-19 22:19:25 +00:00
|
|
|
|
2015-07-30 10:37:58 +00:00
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
{
|
|
|
|
CompileRun(
|
|
|
|
"function testvar(x) {"
|
|
|
|
" y = x;"
|
|
|
|
" y = a;"
|
|
|
|
" return y;"
|
|
|
|
"}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(testvar);"
|
2015-10-01 13:48:05 +00:00
|
|
|
"a = 3;"
|
|
|
|
"testvar({});");
|
|
|
|
|
|
|
|
Handle<JSFunction> f = GetFunction("testvar");
|
|
|
|
|
|
|
|
// There should be two LOAD_ICs, one for a and one for y at the end.
|
2017-02-07 14:05:02 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector =
|
2016-05-27 08:09:12 +00:00
|
|
|
handle(f->feedback_vector(), isolate);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(feedback_vector);
|
2018-03-20 15:16:25 +00:00
|
|
|
CHECK_EQ(3, helper.slot_count());
|
2017-03-23 16:46:53 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kStoreGlobalSloppy);
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
|
2018-03-20 15:16:25 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
|
2015-09-04 08:36:29 +00:00
|
|
|
}
|
2015-07-30 10:37:58 +00:00
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
{
|
|
|
|
CompileRun(
|
|
|
|
"function testprop(x) {"
|
2017-02-06 09:31:52 +00:00
|
|
|
" 'use strict';"
|
2015-10-01 13:48:05 +00:00
|
|
|
" x.blue = a;"
|
|
|
|
"}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(testprop);"
|
2015-10-01 13:48:05 +00:00
|
|
|
"testprop({ blue: 3 });");
|
2015-07-30 10:37:58 +00:00
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
Handle<JSFunction> f = GetFunction("testprop");
|
2015-07-30 10:37:58 +00:00
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
// There should be one LOAD_IC, for the load of a.
|
2018-06-23 09:05:50 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector(f->feedback_vector(), isolate);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(feedback_vector);
|
2015-11-17 13:15:29 +00:00
|
|
|
CHECK_EQ(2, helper.slot_count());
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
|
[ic] name Set/Define/Store property operations more consistently
For background and reasoning, see
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit
This is the first step towards pulling the DefineNamedOwn operation out
of StoreIC.
Summary of the renamed identifiers:
Bytecodes:
- StaNamedProperty -> SetNamedProperty: calls StoreIC and emitted for
normal named property sets like obj.x = 1.
- StaNamedOwnProperty -> DefineNamedOwnProperty: calls
DefineNamedOwnIC (previously StoreOwnIC), and emitted for
initialization of named properties in object literals and named
public class fields.
- StaKeyedProperty -> SetKeyedProperty: calls KeyedStoreIC and emitted
for keyed property sets like obj[x] = 1.
- StaKeyedPropertyAsDefine -> DefineKeyedOwnProperty: calls
DefineKeyedOwnIC (previously KeyedDefineOwnIC) and emitted for
initialization of private class fields and computed public class
fields.
- StaDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral: calls
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral) and emitted for initialization of keyed
properties in object literals and static class initializers. (note
that previously the StoreDataPropertyInLiteral runtime function name
was taken by object spreads and array literal creation instead)
- LdaKeyedProperty -> GetKeyedProperty, LdaNamedProperty ->
GetNamedProperty, LdaNamedPropertyFromSuper ->
GetNamedPropertyFromSuper: we drop the Sta prefix for the property
store operations since the accumulator use is implicit and to make
the wording more natural, for symmetry the Lda prefix for the
property load operations is also dropped.
opcodes:
- (JS)StoreNamed -> (JS)SetNamedProperty: implements set semantics for
named properties, compiled from SetNamedProperty (previously
StaNamedProperty) and lowers to StoreIC or Runtime::kSetNamedProperty
- (JS)StoreNamedOwn -> (JS)DefineNamedOwnProperty: implements define
semantics for initializing named own properties in object literal and
public class fields, compiled from DefineNamedOwnProperty (previously
StaNamedOwnProperty) and lowers to DefineNamedOwnIC
(previously StoreOwnIC)
- (JS)StoreProperty -> (JS)SetKeyedProperty: implements set semantics
for keyed properties, only compiled from SetKeyedProperty(previously
StaKeyedProperty) and lowers to KeyedStoreIC
- (JS)DefineProperty -> (JS)DefineKeyedOwnProperty: implements define
semantics for initialization of private class fields and computed
public class fields, compiled from DefineKeyedOwnProperty (previously
StaKeyedPropertyAsDefine) and calls DefineKeyedOwnIC (previously
KeyedDefineOwnIC).
- (JS)StoreDataPropertyInLiteral ->
(JS)DefineKeyedOwnPropertyInLiteral: implements define semantics for
initialization of keyed properties in object literals and static
class initializers, compiled from DefineKeyedOwnPropertyInLiteral
(previously StaDataPropertyInLiteral) and calls the
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral).
Runtime:
- DefineDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral:
following the bytecode/opcodes change, this is used by
DefineKeyedOwnPropertyInLiteral (previously StaDataPropertyInLiteral)
for object and class literal initialization.
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral_Simple:
it's just a simplified version of DefineDataPropertyInLiteral that
does not update feedback or perform function name configuration.
This is used by object spread and array literal creation. Since we
are renaming DefineDataPropertyInLiteral to
DefineKeyedOwnPropertyInLiteral, rename this simplified version with
a `_Simple` suffix. We can consider merging it into
DefineKeyedOwnPropertyInLiteral in the future. See
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit?disco=AAAAQQIz6mU
- Other changes following the bytecode/IR changes
IC:
- StoreOwn -> DefineNamedOwn: used for initialization of named
properties in object literals and named public class fields.
- StoreOwnIC -> DefineNamedOwnIC
- StoreMode::kStoreOwn -> StoreMode::kDefineNamedOwn
- StoreICMode::kStoreOwn -> StoreICMode::kDefineNamedOwn
- IsStoreOwn() -> IsDefineNamedOwn()
- DefineOwn -> DefineKeyedOwn: IsDefineOwnIC() was already just
IsDefineKeyedOwnIC(), and IsAnyDefineOwn() includes both named and
keyed defines so we don't need an extra generic predicate.
- StoreMode::kDefineOwn -> StoreMode::kDefineKeyedOwn
- StoreICMode::kDefineOwn -> StoreICMode::kDefineKeyedOwn
- IsDefineOwn() -> IsDefineKeyedOwn()
- IsDefineOwnIC() -> IsDefineKeyedOwnIC()
- Removing IsKeyedDefineOwnIC() as its now a duplicate of
IsDefineKeyedOwnIC()
- KeyedDefineOwnIC -> DefineKeyedOwnIC,
KeyedDefineOwnGenericGenerator() -> DefineKeyedOwnGenericGenerator:
make the ordering of terms more consistent
- IsAnyStoreOwn() -> IsAnyDefineOwn(): this includes the renamed and
DefineNamedOwn and DefineKeyedOwn. Also is_any_store_own() is
removed since it's just a duplicate of this.
- IsKeyedStoreOwn() -> IsDefineNamedOwn(): it's unclear where the
"keyed" part came from, but it's only used when DefineNamedOwnIC
(previously StoreOwnIC) reuses KeyedStoreIC, so rename it accordingly
Interpreter & compiler:
- BytecodeArrayBuilder: following bytecode changes
- StoreNamedProperty -> SetNamedProperty
- StoreNamedOwnProperty -> DefineNamedOwnProperty
- StoreKeyedProperty -> SetKeyedProperty
- DefineKeyedProperty -> DefineKeyedOwnProperty
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral
- FeedbackSlotKind:
- kDefineOwnKeyed -> kDefineKeyedOwn: make the ordering of terms more
consistent
- kStoreOwnNamed -> kDefineNamedOwn: following the IC change
- kStoreNamed{Sloppy|Strict} -> kSetNamed{Sloppy|Strict}: only
used in StoreIC for set semantics
- kStoreKeyed{Sloppy|Strict} -> kSetKeyed{Sloppy|Strict}: only used
in KeyedStoreIC for set semantics
- kStoreDataPropertyInLiteral -> kDefineKeyedOwnPropertyInLiteral:
following the IC change
- BytecodeGraphBuilder
- StoreMode::kNormal, kOwn -> NamedStoreMode::kSet, kDefineOwn: this
is only used by BytecodeGraphBuilder::BuildNamedStore() to tell the
difference between SetNamedProperty and DefineNamedOwnProperty
operations.
Not changed:
- StoreIC and KeyedStoreIC currently contain mixed logic for both Set
and Define operations, and the paths are controlled by feedback. The
plan is to refactor the hierarchy like this:
```
- StoreIC
- DefineNamedOwnIC
- SetNamedIC (there could also be a NamedStoreIC if that's helpful)
- KeyedStoreIC
- SetKeyedIC
- DefineKeyedOwnIC
- DefineKeyedOwnICLiteral (could be merged into DefineKeyedOwnIC)
- StoreInArrayLiteralIC
- ...
```
StoreIC and KeyedStoreIC would then contain helpers shared by their
subclasses, therefore it still makes sense to keep the word "Store"
in their names since they would be generic base classes for both set
and define operations.
- The Lda and Sta prefixes of bytecodes not involving object properties
(e.g. Ldar, Star, LdaZero) are kept, since this patch focuses on
property operations, and distinction between Set and Define might be
less relevant or nonexistent for bytecodes not involving object
properties. We could consider rename some of them in future patches
if that's helpful though.
Bug: v8:12548
Change-Id: Ia36997b02f59a87da3247f20e0560a7eb13077f3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3481475
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#79409}
2022-03-08 17:36:04 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kSetNamedStrict);
|
2015-09-04 08:36:29 +00:00
|
|
|
}
|
2015-07-30 10:37:58 +00:00
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
{
|
|
|
|
CompileRun(
|
|
|
|
"function testpropfunc(x) {"
|
|
|
|
" x().blue = a;"
|
|
|
|
" return x().blue;"
|
|
|
|
"}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(testpropfunc);"
|
2015-10-01 13:48:05 +00:00
|
|
|
"function makeresult() { return { blue: 3 }; }"
|
|
|
|
"testpropfunc(makeresult);");
|
|
|
|
|
|
|
|
Handle<JSFunction> f = GetFunction("testpropfunc");
|
|
|
|
|
2016-06-14 13:20:42 +00:00
|
|
|
// There should be 1 LOAD_GLOBAL_IC to load x (in both cases), 2 CALL_ICs
|
|
|
|
// to call x and a LOAD_IC to load blue.
|
2018-06-23 09:05:50 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector(f->feedback_vector(), isolate);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(feedback_vector);
|
2015-11-17 13:15:29 +00:00
|
|
|
CHECK_EQ(5, helper.slot_count());
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kCall);
|
|
|
|
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
|
[ic] name Set/Define/Store property operations more consistently
For background and reasoning, see
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit
This is the first step towards pulling the DefineNamedOwn operation out
of StoreIC.
Summary of the renamed identifiers:
Bytecodes:
- StaNamedProperty -> SetNamedProperty: calls StoreIC and emitted for
normal named property sets like obj.x = 1.
- StaNamedOwnProperty -> DefineNamedOwnProperty: calls
DefineNamedOwnIC (previously StoreOwnIC), and emitted for
initialization of named properties in object literals and named
public class fields.
- StaKeyedProperty -> SetKeyedProperty: calls KeyedStoreIC and emitted
for keyed property sets like obj[x] = 1.
- StaKeyedPropertyAsDefine -> DefineKeyedOwnProperty: calls
DefineKeyedOwnIC (previously KeyedDefineOwnIC) and emitted for
initialization of private class fields and computed public class
fields.
- StaDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral: calls
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral) and emitted for initialization of keyed
properties in object literals and static class initializers. (note
that previously the StoreDataPropertyInLiteral runtime function name
was taken by object spreads and array literal creation instead)
- LdaKeyedProperty -> GetKeyedProperty, LdaNamedProperty ->
GetNamedProperty, LdaNamedPropertyFromSuper ->
GetNamedPropertyFromSuper: we drop the Sta prefix for the property
store operations since the accumulator use is implicit and to make
the wording more natural, for symmetry the Lda prefix for the
property load operations is also dropped.
opcodes:
- (JS)StoreNamed -> (JS)SetNamedProperty: implements set semantics for
named properties, compiled from SetNamedProperty (previously
StaNamedProperty) and lowers to StoreIC or Runtime::kSetNamedProperty
- (JS)StoreNamedOwn -> (JS)DefineNamedOwnProperty: implements define
semantics for initializing named own properties in object literal and
public class fields, compiled from DefineNamedOwnProperty (previously
StaNamedOwnProperty) and lowers to DefineNamedOwnIC
(previously StoreOwnIC)
- (JS)StoreProperty -> (JS)SetKeyedProperty: implements set semantics
for keyed properties, only compiled from SetKeyedProperty(previously
StaKeyedProperty) and lowers to KeyedStoreIC
- (JS)DefineProperty -> (JS)DefineKeyedOwnProperty: implements define
semantics for initialization of private class fields and computed
public class fields, compiled from DefineKeyedOwnProperty (previously
StaKeyedPropertyAsDefine) and calls DefineKeyedOwnIC (previously
KeyedDefineOwnIC).
- (JS)StoreDataPropertyInLiteral ->
(JS)DefineKeyedOwnPropertyInLiteral: implements define semantics for
initialization of keyed properties in object literals and static
class initializers, compiled from DefineKeyedOwnPropertyInLiteral
(previously StaDataPropertyInLiteral) and calls the
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral).
Runtime:
- DefineDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral:
following the bytecode/opcodes change, this is used by
DefineKeyedOwnPropertyInLiteral (previously StaDataPropertyInLiteral)
for object and class literal initialization.
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral_Simple:
it's just a simplified version of DefineDataPropertyInLiteral that
does not update feedback or perform function name configuration.
This is used by object spread and array literal creation. Since we
are renaming DefineDataPropertyInLiteral to
DefineKeyedOwnPropertyInLiteral, rename this simplified version with
a `_Simple` suffix. We can consider merging it into
DefineKeyedOwnPropertyInLiteral in the future. See
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit?disco=AAAAQQIz6mU
- Other changes following the bytecode/IR changes
IC:
- StoreOwn -> DefineNamedOwn: used for initialization of named
properties in object literals and named public class fields.
- StoreOwnIC -> DefineNamedOwnIC
- StoreMode::kStoreOwn -> StoreMode::kDefineNamedOwn
- StoreICMode::kStoreOwn -> StoreICMode::kDefineNamedOwn
- IsStoreOwn() -> IsDefineNamedOwn()
- DefineOwn -> DefineKeyedOwn: IsDefineOwnIC() was already just
IsDefineKeyedOwnIC(), and IsAnyDefineOwn() includes both named and
keyed defines so we don't need an extra generic predicate.
- StoreMode::kDefineOwn -> StoreMode::kDefineKeyedOwn
- StoreICMode::kDefineOwn -> StoreICMode::kDefineKeyedOwn
- IsDefineOwn() -> IsDefineKeyedOwn()
- IsDefineOwnIC() -> IsDefineKeyedOwnIC()
- Removing IsKeyedDefineOwnIC() as its now a duplicate of
IsDefineKeyedOwnIC()
- KeyedDefineOwnIC -> DefineKeyedOwnIC,
KeyedDefineOwnGenericGenerator() -> DefineKeyedOwnGenericGenerator:
make the ordering of terms more consistent
- IsAnyStoreOwn() -> IsAnyDefineOwn(): this includes the renamed and
DefineNamedOwn and DefineKeyedOwn. Also is_any_store_own() is
removed since it's just a duplicate of this.
- IsKeyedStoreOwn() -> IsDefineNamedOwn(): it's unclear where the
"keyed" part came from, but it's only used when DefineNamedOwnIC
(previously StoreOwnIC) reuses KeyedStoreIC, so rename it accordingly
Interpreter & compiler:
- BytecodeArrayBuilder: following bytecode changes
- StoreNamedProperty -> SetNamedProperty
- StoreNamedOwnProperty -> DefineNamedOwnProperty
- StoreKeyedProperty -> SetKeyedProperty
- DefineKeyedProperty -> DefineKeyedOwnProperty
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral
- FeedbackSlotKind:
- kDefineOwnKeyed -> kDefineKeyedOwn: make the ordering of terms more
consistent
- kStoreOwnNamed -> kDefineNamedOwn: following the IC change
- kStoreNamed{Sloppy|Strict} -> kSetNamed{Sloppy|Strict}: only
used in StoreIC for set semantics
- kStoreKeyed{Sloppy|Strict} -> kSetKeyed{Sloppy|Strict}: only used
in KeyedStoreIC for set semantics
- kStoreDataPropertyInLiteral -> kDefineKeyedOwnPropertyInLiteral:
following the IC change
- BytecodeGraphBuilder
- StoreMode::kNormal, kOwn -> NamedStoreMode::kSet, kDefineOwn: this
is only used by BytecodeGraphBuilder::BuildNamedStore() to tell the
difference between SetNamedProperty and DefineNamedOwnProperty
operations.
Not changed:
- StoreIC and KeyedStoreIC currently contain mixed logic for both Set
and Define operations, and the paths are controlled by feedback. The
plan is to refactor the hierarchy like this:
```
- StoreIC
- DefineNamedOwnIC
- SetNamedIC (there could also be a NamedStoreIC if that's helpful)
- KeyedStoreIC
- SetKeyedIC
- DefineKeyedOwnIC
- DefineKeyedOwnICLiteral (could be merged into DefineKeyedOwnIC)
- StoreInArrayLiteralIC
- ...
```
StoreIC and KeyedStoreIC would then contain helpers shared by their
subclasses, therefore it still makes sense to keep the word "Store"
in their names since they would be generic base classes for both set
and define operations.
- The Lda and Sta prefixes of bytecodes not involving object properties
(e.g. Ldar, Star, LdaZero) are kept, since this patch focuses on
property operations, and distinction between Set and Define might be
less relevant or nonexistent for bytecodes not involving object
properties. We could consider rename some of them in future patches
if that's helpful though.
Bug: v8:12548
Change-Id: Ia36997b02f59a87da3247f20e0560a7eb13077f3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3481475
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#79409}
2022-03-08 17:36:04 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kSetNamedSloppy);
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kCall);
|
|
|
|
CHECK_SLOT_KIND(helper, 4, FeedbackSlotKind::kLoadProperty);
|
2015-09-04 08:36:29 +00:00
|
|
|
}
|
2015-07-30 10:37:58 +00:00
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
{
|
|
|
|
CompileRun(
|
|
|
|
"function testkeyedprop(x) {"
|
|
|
|
" x[0] = a;"
|
|
|
|
" return x[0];"
|
|
|
|
"}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(testkeyedprop);"
|
2015-10-01 13:48:05 +00:00
|
|
|
"testkeyedprop([0, 1, 2]);");
|
|
|
|
|
|
|
|
Handle<JSFunction> f = GetFunction("testkeyedprop");
|
|
|
|
|
2016-06-14 13:20:42 +00:00
|
|
|
// There should be 1 LOAD_GLOBAL_ICs for the load of a, and one
|
|
|
|
// KEYED_LOAD_IC for the load of x[0] in the return statement.
|
2018-06-23 09:05:50 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector(f->feedback_vector(), isolate);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(feedback_vector);
|
2015-11-17 13:15:29 +00:00
|
|
|
CHECK_EQ(3, helper.slot_count());
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
|
[ic] name Set/Define/Store property operations more consistently
For background and reasoning, see
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit
This is the first step towards pulling the DefineNamedOwn operation out
of StoreIC.
Summary of the renamed identifiers:
Bytecodes:
- StaNamedProperty -> SetNamedProperty: calls StoreIC and emitted for
normal named property sets like obj.x = 1.
- StaNamedOwnProperty -> DefineNamedOwnProperty: calls
DefineNamedOwnIC (previously StoreOwnIC), and emitted for
initialization of named properties in object literals and named
public class fields.
- StaKeyedProperty -> SetKeyedProperty: calls KeyedStoreIC and emitted
for keyed property sets like obj[x] = 1.
- StaKeyedPropertyAsDefine -> DefineKeyedOwnProperty: calls
DefineKeyedOwnIC (previously KeyedDefineOwnIC) and emitted for
initialization of private class fields and computed public class
fields.
- StaDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral: calls
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral) and emitted for initialization of keyed
properties in object literals and static class initializers. (note
that previously the StoreDataPropertyInLiteral runtime function name
was taken by object spreads and array literal creation instead)
- LdaKeyedProperty -> GetKeyedProperty, LdaNamedProperty ->
GetNamedProperty, LdaNamedPropertyFromSuper ->
GetNamedPropertyFromSuper: we drop the Sta prefix for the property
store operations since the accumulator use is implicit and to make
the wording more natural, for symmetry the Lda prefix for the
property load operations is also dropped.
opcodes:
- (JS)StoreNamed -> (JS)SetNamedProperty: implements set semantics for
named properties, compiled from SetNamedProperty (previously
StaNamedProperty) and lowers to StoreIC or Runtime::kSetNamedProperty
- (JS)StoreNamedOwn -> (JS)DefineNamedOwnProperty: implements define
semantics for initializing named own properties in object literal and
public class fields, compiled from DefineNamedOwnProperty (previously
StaNamedOwnProperty) and lowers to DefineNamedOwnIC
(previously StoreOwnIC)
- (JS)StoreProperty -> (JS)SetKeyedProperty: implements set semantics
for keyed properties, only compiled from SetKeyedProperty(previously
StaKeyedProperty) and lowers to KeyedStoreIC
- (JS)DefineProperty -> (JS)DefineKeyedOwnProperty: implements define
semantics for initialization of private class fields and computed
public class fields, compiled from DefineKeyedOwnProperty (previously
StaKeyedPropertyAsDefine) and calls DefineKeyedOwnIC (previously
KeyedDefineOwnIC).
- (JS)StoreDataPropertyInLiteral ->
(JS)DefineKeyedOwnPropertyInLiteral: implements define semantics for
initialization of keyed properties in object literals and static
class initializers, compiled from DefineKeyedOwnPropertyInLiteral
(previously StaDataPropertyInLiteral) and calls the
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral).
Runtime:
- DefineDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral:
following the bytecode/opcodes change, this is used by
DefineKeyedOwnPropertyInLiteral (previously StaDataPropertyInLiteral)
for object and class literal initialization.
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral_Simple:
it's just a simplified version of DefineDataPropertyInLiteral that
does not update feedback or perform function name configuration.
This is used by object spread and array literal creation. Since we
are renaming DefineDataPropertyInLiteral to
DefineKeyedOwnPropertyInLiteral, rename this simplified version with
a `_Simple` suffix. We can consider merging it into
DefineKeyedOwnPropertyInLiteral in the future. See
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit?disco=AAAAQQIz6mU
- Other changes following the bytecode/IR changes
IC:
- StoreOwn -> DefineNamedOwn: used for initialization of named
properties in object literals and named public class fields.
- StoreOwnIC -> DefineNamedOwnIC
- StoreMode::kStoreOwn -> StoreMode::kDefineNamedOwn
- StoreICMode::kStoreOwn -> StoreICMode::kDefineNamedOwn
- IsStoreOwn() -> IsDefineNamedOwn()
- DefineOwn -> DefineKeyedOwn: IsDefineOwnIC() was already just
IsDefineKeyedOwnIC(), and IsAnyDefineOwn() includes both named and
keyed defines so we don't need an extra generic predicate.
- StoreMode::kDefineOwn -> StoreMode::kDefineKeyedOwn
- StoreICMode::kDefineOwn -> StoreICMode::kDefineKeyedOwn
- IsDefineOwn() -> IsDefineKeyedOwn()
- IsDefineOwnIC() -> IsDefineKeyedOwnIC()
- Removing IsKeyedDefineOwnIC() as its now a duplicate of
IsDefineKeyedOwnIC()
- KeyedDefineOwnIC -> DefineKeyedOwnIC,
KeyedDefineOwnGenericGenerator() -> DefineKeyedOwnGenericGenerator:
make the ordering of terms more consistent
- IsAnyStoreOwn() -> IsAnyDefineOwn(): this includes the renamed and
DefineNamedOwn and DefineKeyedOwn. Also is_any_store_own() is
removed since it's just a duplicate of this.
- IsKeyedStoreOwn() -> IsDefineNamedOwn(): it's unclear where the
"keyed" part came from, but it's only used when DefineNamedOwnIC
(previously StoreOwnIC) reuses KeyedStoreIC, so rename it accordingly
Interpreter & compiler:
- BytecodeArrayBuilder: following bytecode changes
- StoreNamedProperty -> SetNamedProperty
- StoreNamedOwnProperty -> DefineNamedOwnProperty
- StoreKeyedProperty -> SetKeyedProperty
- DefineKeyedProperty -> DefineKeyedOwnProperty
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral
- FeedbackSlotKind:
- kDefineOwnKeyed -> kDefineKeyedOwn: make the ordering of terms more
consistent
- kStoreOwnNamed -> kDefineNamedOwn: following the IC change
- kStoreNamed{Sloppy|Strict} -> kSetNamed{Sloppy|Strict}: only
used in StoreIC for set semantics
- kStoreKeyed{Sloppy|Strict} -> kSetKeyed{Sloppy|Strict}: only used
in KeyedStoreIC for set semantics
- kStoreDataPropertyInLiteral -> kDefineKeyedOwnPropertyInLiteral:
following the IC change
- BytecodeGraphBuilder
- StoreMode::kNormal, kOwn -> NamedStoreMode::kSet, kDefineOwn: this
is only used by BytecodeGraphBuilder::BuildNamedStore() to tell the
difference between SetNamedProperty and DefineNamedOwnProperty
operations.
Not changed:
- StoreIC and KeyedStoreIC currently contain mixed logic for both Set
and Define operations, and the paths are controlled by feedback. The
plan is to refactor the hierarchy like this:
```
- StoreIC
- DefineNamedOwnIC
- SetNamedIC (there could also be a NamedStoreIC if that's helpful)
- KeyedStoreIC
- SetKeyedIC
- DefineKeyedOwnIC
- DefineKeyedOwnICLiteral (could be merged into DefineKeyedOwnIC)
- StoreInArrayLiteralIC
- ...
```
StoreIC and KeyedStoreIC would then contain helpers shared by their
subclasses, therefore it still makes sense to keep the word "Store"
in their names since they would be generic base classes for both set
and define operations.
- The Lda and Sta prefixes of bytecodes not involving object properties
(e.g. Ldar, Star, LdaZero) are kept, since this patch focuses on
property operations, and distinction between Set and Define might be
less relevant or nonexistent for bytecodes not involving object
properties. We could consider rename some of them in future patches
if that's helpful though.
Bug: v8:12548
Change-Id: Ia36997b02f59a87da3247f20e0560a7eb13077f3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3481475
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#79409}
2022-03-08 17:36:04 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kSetKeyedSloppy);
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kLoadKeyed);
|
2017-02-06 09:31:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
CompileRun(
|
|
|
|
"function testkeyedprop(x) {"
|
|
|
|
" 'use strict';"
|
|
|
|
" x[0] = a;"
|
|
|
|
" return x[0];"
|
|
|
|
"}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(testkeyedprop);"
|
2017-02-06 09:31:52 +00:00
|
|
|
"testkeyedprop([0, 1, 2]);");
|
|
|
|
|
|
|
|
Handle<JSFunction> f = GetFunction("testkeyedprop");
|
|
|
|
|
|
|
|
// There should be 1 LOAD_GLOBAL_ICs for the load of a, and one
|
|
|
|
// KEYED_LOAD_IC for the load of x[0] in the return statement.
|
2018-06-23 09:05:50 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector(f->feedback_vector(), isolate);
|
2017-02-06 09:31:52 +00:00
|
|
|
FeedbackVectorHelper helper(feedback_vector);
|
|
|
|
CHECK_EQ(3, helper.slot_count());
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
|
[ic] name Set/Define/Store property operations more consistently
For background and reasoning, see
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit
This is the first step towards pulling the DefineNamedOwn operation out
of StoreIC.
Summary of the renamed identifiers:
Bytecodes:
- StaNamedProperty -> SetNamedProperty: calls StoreIC and emitted for
normal named property sets like obj.x = 1.
- StaNamedOwnProperty -> DefineNamedOwnProperty: calls
DefineNamedOwnIC (previously StoreOwnIC), and emitted for
initialization of named properties in object literals and named
public class fields.
- StaKeyedProperty -> SetKeyedProperty: calls KeyedStoreIC and emitted
for keyed property sets like obj[x] = 1.
- StaKeyedPropertyAsDefine -> DefineKeyedOwnProperty: calls
DefineKeyedOwnIC (previously KeyedDefineOwnIC) and emitted for
initialization of private class fields and computed public class
fields.
- StaDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral: calls
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral) and emitted for initialization of keyed
properties in object literals and static class initializers. (note
that previously the StoreDataPropertyInLiteral runtime function name
was taken by object spreads and array literal creation instead)
- LdaKeyedProperty -> GetKeyedProperty, LdaNamedProperty ->
GetNamedProperty, LdaNamedPropertyFromSuper ->
GetNamedPropertyFromSuper: we drop the Sta prefix for the property
store operations since the accumulator use is implicit and to make
the wording more natural, for symmetry the Lda prefix for the
property load operations is also dropped.
opcodes:
- (JS)StoreNamed -> (JS)SetNamedProperty: implements set semantics for
named properties, compiled from SetNamedProperty (previously
StaNamedProperty) and lowers to StoreIC or Runtime::kSetNamedProperty
- (JS)StoreNamedOwn -> (JS)DefineNamedOwnProperty: implements define
semantics for initializing named own properties in object literal and
public class fields, compiled from DefineNamedOwnProperty (previously
StaNamedOwnProperty) and lowers to DefineNamedOwnIC
(previously StoreOwnIC)
- (JS)StoreProperty -> (JS)SetKeyedProperty: implements set semantics
for keyed properties, only compiled from SetKeyedProperty(previously
StaKeyedProperty) and lowers to KeyedStoreIC
- (JS)DefineProperty -> (JS)DefineKeyedOwnProperty: implements define
semantics for initialization of private class fields and computed
public class fields, compiled from DefineKeyedOwnProperty (previously
StaKeyedPropertyAsDefine) and calls DefineKeyedOwnIC (previously
KeyedDefineOwnIC).
- (JS)StoreDataPropertyInLiteral ->
(JS)DefineKeyedOwnPropertyInLiteral: implements define semantics for
initialization of keyed properties in object literals and static
class initializers, compiled from DefineKeyedOwnPropertyInLiteral
(previously StaDataPropertyInLiteral) and calls the
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral).
Runtime:
- DefineDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral:
following the bytecode/opcodes change, this is used by
DefineKeyedOwnPropertyInLiteral (previously StaDataPropertyInLiteral)
for object and class literal initialization.
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral_Simple:
it's just a simplified version of DefineDataPropertyInLiteral that
does not update feedback or perform function name configuration.
This is used by object spread and array literal creation. Since we
are renaming DefineDataPropertyInLiteral to
DefineKeyedOwnPropertyInLiteral, rename this simplified version with
a `_Simple` suffix. We can consider merging it into
DefineKeyedOwnPropertyInLiteral in the future. See
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit?disco=AAAAQQIz6mU
- Other changes following the bytecode/IR changes
IC:
- StoreOwn -> DefineNamedOwn: used for initialization of named
properties in object literals and named public class fields.
- StoreOwnIC -> DefineNamedOwnIC
- StoreMode::kStoreOwn -> StoreMode::kDefineNamedOwn
- StoreICMode::kStoreOwn -> StoreICMode::kDefineNamedOwn
- IsStoreOwn() -> IsDefineNamedOwn()
- DefineOwn -> DefineKeyedOwn: IsDefineOwnIC() was already just
IsDefineKeyedOwnIC(), and IsAnyDefineOwn() includes both named and
keyed defines so we don't need an extra generic predicate.
- StoreMode::kDefineOwn -> StoreMode::kDefineKeyedOwn
- StoreICMode::kDefineOwn -> StoreICMode::kDefineKeyedOwn
- IsDefineOwn() -> IsDefineKeyedOwn()
- IsDefineOwnIC() -> IsDefineKeyedOwnIC()
- Removing IsKeyedDefineOwnIC() as its now a duplicate of
IsDefineKeyedOwnIC()
- KeyedDefineOwnIC -> DefineKeyedOwnIC,
KeyedDefineOwnGenericGenerator() -> DefineKeyedOwnGenericGenerator:
make the ordering of terms more consistent
- IsAnyStoreOwn() -> IsAnyDefineOwn(): this includes the renamed and
DefineNamedOwn and DefineKeyedOwn. Also is_any_store_own() is
removed since it's just a duplicate of this.
- IsKeyedStoreOwn() -> IsDefineNamedOwn(): it's unclear where the
"keyed" part came from, but it's only used when DefineNamedOwnIC
(previously StoreOwnIC) reuses KeyedStoreIC, so rename it accordingly
Interpreter & compiler:
- BytecodeArrayBuilder: following bytecode changes
- StoreNamedProperty -> SetNamedProperty
- StoreNamedOwnProperty -> DefineNamedOwnProperty
- StoreKeyedProperty -> SetKeyedProperty
- DefineKeyedProperty -> DefineKeyedOwnProperty
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral
- FeedbackSlotKind:
- kDefineOwnKeyed -> kDefineKeyedOwn: make the ordering of terms more
consistent
- kStoreOwnNamed -> kDefineNamedOwn: following the IC change
- kStoreNamed{Sloppy|Strict} -> kSetNamed{Sloppy|Strict}: only
used in StoreIC for set semantics
- kStoreKeyed{Sloppy|Strict} -> kSetKeyed{Sloppy|Strict}: only used
in KeyedStoreIC for set semantics
- kStoreDataPropertyInLiteral -> kDefineKeyedOwnPropertyInLiteral:
following the IC change
- BytecodeGraphBuilder
- StoreMode::kNormal, kOwn -> NamedStoreMode::kSet, kDefineOwn: this
is only used by BytecodeGraphBuilder::BuildNamedStore() to tell the
difference between SetNamedProperty and DefineNamedOwnProperty
operations.
Not changed:
- StoreIC and KeyedStoreIC currently contain mixed logic for both Set
and Define operations, and the paths are controlled by feedback. The
plan is to refactor the hierarchy like this:
```
- StoreIC
- DefineNamedOwnIC
- SetNamedIC (there could also be a NamedStoreIC if that's helpful)
- KeyedStoreIC
- SetKeyedIC
- DefineKeyedOwnIC
- DefineKeyedOwnICLiteral (could be merged into DefineKeyedOwnIC)
- StoreInArrayLiteralIC
- ...
```
StoreIC and KeyedStoreIC would then contain helpers shared by their
subclasses, therefore it still makes sense to keep the word "Store"
in their names since they would be generic base classes for both set
and define operations.
- The Lda and Sta prefixes of bytecodes not involving object properties
(e.g. Ldar, Star, LdaZero) are kept, since this patch focuses on
property operations, and distinction between Set and Define might be
less relevant or nonexistent for bytecodes not involving object
properties. We could consider rename some of them in future patches
if that's helpful though.
Bug: v8:12548
Change-Id: Ia36997b02f59a87da3247f20e0560a7eb13077f3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3481475
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#79409}
2022-03-08 17:36:04 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kSetKeyedStrict);
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kLoadKeyed);
|
2015-09-04 08:36:29 +00:00
|
|
|
}
|
2015-07-30 10:37:58 +00:00
|
|
|
|
2015-10-01 13:48:05 +00:00
|
|
|
{
|
|
|
|
CompileRun(
|
|
|
|
"function testcompound(x) {"
|
2017-02-06 09:31:52 +00:00
|
|
|
" 'use strict';"
|
2015-10-01 13:48:05 +00:00
|
|
|
" x.old = x.young = x.in_between = a;"
|
|
|
|
" return x.old + x.young;"
|
|
|
|
"}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(testcompound);"
|
2015-10-01 13:48:05 +00:00
|
|
|
"testcompound({ old: 3, young: 3, in_between: 3 });");
|
|
|
|
|
|
|
|
Handle<JSFunction> f = GetFunction("testcompound");
|
|
|
|
|
2016-06-14 13:20:42 +00:00
|
|
|
// There should be 1 LOAD_GLOBAL_IC for load of a and 2 LOAD_ICs, for load
|
|
|
|
// of x.old and x.young.
|
2018-06-23 09:05:50 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector(f->feedback_vector(), isolate);
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(feedback_vector);
|
2016-08-08 01:15:22 +00:00
|
|
|
CHECK_EQ(7, helper.slot_count());
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
|
[ic] name Set/Define/Store property operations more consistently
For background and reasoning, see
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit
This is the first step towards pulling the DefineNamedOwn operation out
of StoreIC.
Summary of the renamed identifiers:
Bytecodes:
- StaNamedProperty -> SetNamedProperty: calls StoreIC and emitted for
normal named property sets like obj.x = 1.
- StaNamedOwnProperty -> DefineNamedOwnProperty: calls
DefineNamedOwnIC (previously StoreOwnIC), and emitted for
initialization of named properties in object literals and named
public class fields.
- StaKeyedProperty -> SetKeyedProperty: calls KeyedStoreIC and emitted
for keyed property sets like obj[x] = 1.
- StaKeyedPropertyAsDefine -> DefineKeyedOwnProperty: calls
DefineKeyedOwnIC (previously KeyedDefineOwnIC) and emitted for
initialization of private class fields and computed public class
fields.
- StaDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral: calls
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral) and emitted for initialization of keyed
properties in object literals and static class initializers. (note
that previously the StoreDataPropertyInLiteral runtime function name
was taken by object spreads and array literal creation instead)
- LdaKeyedProperty -> GetKeyedProperty, LdaNamedProperty ->
GetNamedProperty, LdaNamedPropertyFromSuper ->
GetNamedPropertyFromSuper: we drop the Sta prefix for the property
store operations since the accumulator use is implicit and to make
the wording more natural, for symmetry the Lda prefix for the
property load operations is also dropped.
opcodes:
- (JS)StoreNamed -> (JS)SetNamedProperty: implements set semantics for
named properties, compiled from SetNamedProperty (previously
StaNamedProperty) and lowers to StoreIC or Runtime::kSetNamedProperty
- (JS)StoreNamedOwn -> (JS)DefineNamedOwnProperty: implements define
semantics for initializing named own properties in object literal and
public class fields, compiled from DefineNamedOwnProperty (previously
StaNamedOwnProperty) and lowers to DefineNamedOwnIC
(previously StoreOwnIC)
- (JS)StoreProperty -> (JS)SetKeyedProperty: implements set semantics
for keyed properties, only compiled from SetKeyedProperty(previously
StaKeyedProperty) and lowers to KeyedStoreIC
- (JS)DefineProperty -> (JS)DefineKeyedOwnProperty: implements define
semantics for initialization of private class fields and computed
public class fields, compiled from DefineKeyedOwnProperty (previously
StaKeyedPropertyAsDefine) and calls DefineKeyedOwnIC (previously
KeyedDefineOwnIC).
- (JS)StoreDataPropertyInLiteral ->
(JS)DefineKeyedOwnPropertyInLiteral: implements define semantics for
initialization of keyed properties in object literals and static
class initializers, compiled from DefineKeyedOwnPropertyInLiteral
(previously StaDataPropertyInLiteral) and calls the
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral).
Runtime:
- DefineDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral:
following the bytecode/opcodes change, this is used by
DefineKeyedOwnPropertyInLiteral (previously StaDataPropertyInLiteral)
for object and class literal initialization.
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral_Simple:
it's just a simplified version of DefineDataPropertyInLiteral that
does not update feedback or perform function name configuration.
This is used by object spread and array literal creation. Since we
are renaming DefineDataPropertyInLiteral to
DefineKeyedOwnPropertyInLiteral, rename this simplified version with
a `_Simple` suffix. We can consider merging it into
DefineKeyedOwnPropertyInLiteral in the future. See
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit?disco=AAAAQQIz6mU
- Other changes following the bytecode/IR changes
IC:
- StoreOwn -> DefineNamedOwn: used for initialization of named
properties in object literals and named public class fields.
- StoreOwnIC -> DefineNamedOwnIC
- StoreMode::kStoreOwn -> StoreMode::kDefineNamedOwn
- StoreICMode::kStoreOwn -> StoreICMode::kDefineNamedOwn
- IsStoreOwn() -> IsDefineNamedOwn()
- DefineOwn -> DefineKeyedOwn: IsDefineOwnIC() was already just
IsDefineKeyedOwnIC(), and IsAnyDefineOwn() includes both named and
keyed defines so we don't need an extra generic predicate.
- StoreMode::kDefineOwn -> StoreMode::kDefineKeyedOwn
- StoreICMode::kDefineOwn -> StoreICMode::kDefineKeyedOwn
- IsDefineOwn() -> IsDefineKeyedOwn()
- IsDefineOwnIC() -> IsDefineKeyedOwnIC()
- Removing IsKeyedDefineOwnIC() as its now a duplicate of
IsDefineKeyedOwnIC()
- KeyedDefineOwnIC -> DefineKeyedOwnIC,
KeyedDefineOwnGenericGenerator() -> DefineKeyedOwnGenericGenerator:
make the ordering of terms more consistent
- IsAnyStoreOwn() -> IsAnyDefineOwn(): this includes the renamed and
DefineNamedOwn and DefineKeyedOwn. Also is_any_store_own() is
removed since it's just a duplicate of this.
- IsKeyedStoreOwn() -> IsDefineNamedOwn(): it's unclear where the
"keyed" part came from, but it's only used when DefineNamedOwnIC
(previously StoreOwnIC) reuses KeyedStoreIC, so rename it accordingly
Interpreter & compiler:
- BytecodeArrayBuilder: following bytecode changes
- StoreNamedProperty -> SetNamedProperty
- StoreNamedOwnProperty -> DefineNamedOwnProperty
- StoreKeyedProperty -> SetKeyedProperty
- DefineKeyedProperty -> DefineKeyedOwnProperty
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral
- FeedbackSlotKind:
- kDefineOwnKeyed -> kDefineKeyedOwn: make the ordering of terms more
consistent
- kStoreOwnNamed -> kDefineNamedOwn: following the IC change
- kStoreNamed{Sloppy|Strict} -> kSetNamed{Sloppy|Strict}: only
used in StoreIC for set semantics
- kStoreKeyed{Sloppy|Strict} -> kSetKeyed{Sloppy|Strict}: only used
in KeyedStoreIC for set semantics
- kStoreDataPropertyInLiteral -> kDefineKeyedOwnPropertyInLiteral:
following the IC change
- BytecodeGraphBuilder
- StoreMode::kNormal, kOwn -> NamedStoreMode::kSet, kDefineOwn: this
is only used by BytecodeGraphBuilder::BuildNamedStore() to tell the
difference between SetNamedProperty and DefineNamedOwnProperty
operations.
Not changed:
- StoreIC and KeyedStoreIC currently contain mixed logic for both Set
and Define operations, and the paths are controlled by feedback. The
plan is to refactor the hierarchy like this:
```
- StoreIC
- DefineNamedOwnIC
- SetNamedIC (there could also be a NamedStoreIC if that's helpful)
- KeyedStoreIC
- SetKeyedIC
- DefineKeyedOwnIC
- DefineKeyedOwnICLiteral (could be merged into DefineKeyedOwnIC)
- StoreInArrayLiteralIC
- ...
```
StoreIC and KeyedStoreIC would then contain helpers shared by their
subclasses, therefore it still makes sense to keep the word "Store"
in their names since they would be generic base classes for both set
and define operations.
- The Lda and Sta prefixes of bytecodes not involving object properties
(e.g. Ldar, Star, LdaZero) are kept, since this patch focuses on
property operations, and distinction between Set and Define might be
less relevant or nonexistent for bytecodes not involving object
properties. We could consider rename some of them in future patches
if that's helpful though.
Bug: v8:12548
Change-Id: Ia36997b02f59a87da3247f20e0560a7eb13077f3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3481475
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#79409}
2022-03-08 17:36:04 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kSetNamedStrict);
|
|
|
|
CHECK_SLOT_KIND(helper, 2, FeedbackSlotKind::kSetNamedStrict);
|
|
|
|
CHECK_SLOT_KIND(helper, 3, FeedbackSlotKind::kSetNamedStrict);
|
2017-10-19 15:12:42 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 4, FeedbackSlotKind::kBinaryOp);
|
2017-02-07 17:49:58 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 5, FeedbackSlotKind::kLoadProperty);
|
2017-10-19 15:12:42 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 6, FeedbackSlotKind::kLoadProperty);
|
2015-09-04 08:36:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(VectorStoreICBasic) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2015-09-04 08:36:29 +00:00
|
|
|
|
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
|
|
|
|
CompileRun(
|
|
|
|
"function f(a) {"
|
|
|
|
" a.foo = 5;"
|
2019-03-25 15:05:47 +00:00
|
|
|
"};"
|
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2015-09-04 08:36:29 +00:00
|
|
|
"var a = { foo: 3 };"
|
|
|
|
"f(a);"
|
|
|
|
"f(a);"
|
|
|
|
"f(a);");
|
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
|
|
|
// There should be one IC slot.
|
2018-06-23 09:05:50 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector(f->feedback_vector(), f->GetIsolate());
|
2015-10-01 13:48:05 +00:00
|
|
|
FeedbackVectorHelper helper(feedback_vector);
|
|
|
|
CHECK_EQ(1, helper.slot_count());
|
2017-02-07 15:19:35 +00:00
|
|
|
FeedbackSlot slot(0);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, slot);
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2015-07-30 10:37:58 +00:00
|
|
|
}
|
2015-09-30 13:46:56 +00:00
|
|
|
|
[ic] name Set/Define/Store property operations more consistently
For background and reasoning, see
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit
This is the first step towards pulling the DefineNamedOwn operation out
of StoreIC.
Summary of the renamed identifiers:
Bytecodes:
- StaNamedProperty -> SetNamedProperty: calls StoreIC and emitted for
normal named property sets like obj.x = 1.
- StaNamedOwnProperty -> DefineNamedOwnProperty: calls
DefineNamedOwnIC (previously StoreOwnIC), and emitted for
initialization of named properties in object literals and named
public class fields.
- StaKeyedProperty -> SetKeyedProperty: calls KeyedStoreIC and emitted
for keyed property sets like obj[x] = 1.
- StaKeyedPropertyAsDefine -> DefineKeyedOwnProperty: calls
DefineKeyedOwnIC (previously KeyedDefineOwnIC) and emitted for
initialization of private class fields and computed public class
fields.
- StaDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral: calls
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral) and emitted for initialization of keyed
properties in object literals and static class initializers. (note
that previously the StoreDataPropertyInLiteral runtime function name
was taken by object spreads and array literal creation instead)
- LdaKeyedProperty -> GetKeyedProperty, LdaNamedProperty ->
GetNamedProperty, LdaNamedPropertyFromSuper ->
GetNamedPropertyFromSuper: we drop the Sta prefix for the property
store operations since the accumulator use is implicit and to make
the wording more natural, for symmetry the Lda prefix for the
property load operations is also dropped.
opcodes:
- (JS)StoreNamed -> (JS)SetNamedProperty: implements set semantics for
named properties, compiled from SetNamedProperty (previously
StaNamedProperty) and lowers to StoreIC or Runtime::kSetNamedProperty
- (JS)StoreNamedOwn -> (JS)DefineNamedOwnProperty: implements define
semantics for initializing named own properties in object literal and
public class fields, compiled from DefineNamedOwnProperty (previously
StaNamedOwnProperty) and lowers to DefineNamedOwnIC
(previously StoreOwnIC)
- (JS)StoreProperty -> (JS)SetKeyedProperty: implements set semantics
for keyed properties, only compiled from SetKeyedProperty(previously
StaKeyedProperty) and lowers to KeyedStoreIC
- (JS)DefineProperty -> (JS)DefineKeyedOwnProperty: implements define
semantics for initialization of private class fields and computed
public class fields, compiled from DefineKeyedOwnProperty (previously
StaKeyedPropertyAsDefine) and calls DefineKeyedOwnIC (previously
KeyedDefineOwnIC).
- (JS)StoreDataPropertyInLiteral ->
(JS)DefineKeyedOwnPropertyInLiteral: implements define semantics for
initialization of keyed properties in object literals and static
class initializers, compiled from DefineKeyedOwnPropertyInLiteral
(previously StaDataPropertyInLiteral) and calls the
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral).
Runtime:
- DefineDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral:
following the bytecode/opcodes change, this is used by
DefineKeyedOwnPropertyInLiteral (previously StaDataPropertyInLiteral)
for object and class literal initialization.
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral_Simple:
it's just a simplified version of DefineDataPropertyInLiteral that
does not update feedback or perform function name configuration.
This is used by object spread and array literal creation. Since we
are renaming DefineDataPropertyInLiteral to
DefineKeyedOwnPropertyInLiteral, rename this simplified version with
a `_Simple` suffix. We can consider merging it into
DefineKeyedOwnPropertyInLiteral in the future. See
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit?disco=AAAAQQIz6mU
- Other changes following the bytecode/IR changes
IC:
- StoreOwn -> DefineNamedOwn: used for initialization of named
properties in object literals and named public class fields.
- StoreOwnIC -> DefineNamedOwnIC
- StoreMode::kStoreOwn -> StoreMode::kDefineNamedOwn
- StoreICMode::kStoreOwn -> StoreICMode::kDefineNamedOwn
- IsStoreOwn() -> IsDefineNamedOwn()
- DefineOwn -> DefineKeyedOwn: IsDefineOwnIC() was already just
IsDefineKeyedOwnIC(), and IsAnyDefineOwn() includes both named and
keyed defines so we don't need an extra generic predicate.
- StoreMode::kDefineOwn -> StoreMode::kDefineKeyedOwn
- StoreICMode::kDefineOwn -> StoreICMode::kDefineKeyedOwn
- IsDefineOwn() -> IsDefineKeyedOwn()
- IsDefineOwnIC() -> IsDefineKeyedOwnIC()
- Removing IsKeyedDefineOwnIC() as its now a duplicate of
IsDefineKeyedOwnIC()
- KeyedDefineOwnIC -> DefineKeyedOwnIC,
KeyedDefineOwnGenericGenerator() -> DefineKeyedOwnGenericGenerator:
make the ordering of terms more consistent
- IsAnyStoreOwn() -> IsAnyDefineOwn(): this includes the renamed and
DefineNamedOwn and DefineKeyedOwn. Also is_any_store_own() is
removed since it's just a duplicate of this.
- IsKeyedStoreOwn() -> IsDefineNamedOwn(): it's unclear where the
"keyed" part came from, but it's only used when DefineNamedOwnIC
(previously StoreOwnIC) reuses KeyedStoreIC, so rename it accordingly
Interpreter & compiler:
- BytecodeArrayBuilder: following bytecode changes
- StoreNamedProperty -> SetNamedProperty
- StoreNamedOwnProperty -> DefineNamedOwnProperty
- StoreKeyedProperty -> SetKeyedProperty
- DefineKeyedProperty -> DefineKeyedOwnProperty
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral
- FeedbackSlotKind:
- kDefineOwnKeyed -> kDefineKeyedOwn: make the ordering of terms more
consistent
- kStoreOwnNamed -> kDefineNamedOwn: following the IC change
- kStoreNamed{Sloppy|Strict} -> kSetNamed{Sloppy|Strict}: only
used in StoreIC for set semantics
- kStoreKeyed{Sloppy|Strict} -> kSetKeyed{Sloppy|Strict}: only used
in KeyedStoreIC for set semantics
- kStoreDataPropertyInLiteral -> kDefineKeyedOwnPropertyInLiteral:
following the IC change
- BytecodeGraphBuilder
- StoreMode::kNormal, kOwn -> NamedStoreMode::kSet, kDefineOwn: this
is only used by BytecodeGraphBuilder::BuildNamedStore() to tell the
difference between SetNamedProperty and DefineNamedOwnProperty
operations.
Not changed:
- StoreIC and KeyedStoreIC currently contain mixed logic for both Set
and Define operations, and the paths are controlled by feedback. The
plan is to refactor the hierarchy like this:
```
- StoreIC
- DefineNamedOwnIC
- SetNamedIC (there could also be a NamedStoreIC if that's helpful)
- KeyedStoreIC
- SetKeyedIC
- DefineKeyedOwnIC
- DefineKeyedOwnICLiteral (could be merged into DefineKeyedOwnIC)
- StoreInArrayLiteralIC
- ...
```
StoreIC and KeyedStoreIC would then contain helpers shared by their
subclasses, therefore it still makes sense to keep the word "Store"
in their names since they would be generic base classes for both set
and define operations.
- The Lda and Sta prefixes of bytecodes not involving object properties
(e.g. Ldar, Star, LdaZero) are kept, since this patch focuses on
property operations, and distinction between Set and Define might be
less relevant or nonexistent for bytecodes not involving object
properties. We could consider rename some of them in future patches
if that's helpful though.
Bug: v8:12548
Change-Id: Ia36997b02f59a87da3247f20e0560a7eb13077f3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3481475
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#79409}
2022-03-08 17:36:04 +00:00
|
|
|
TEST(DefineNamedOwnIC) {
|
2018-10-19 22:19:25 +00:00
|
|
|
if (!i::FLAG_use_ic) return;
|
2022-04-28 14:22:23 +00:00
|
|
|
if (i::FLAG_always_turbofan) return;
|
2019-03-25 15:05:47 +00:00
|
|
|
FLAG_allow_natives_syntax = true;
|
2017-02-17 15:15:07 +00:00
|
|
|
|
|
|
|
CcTest::InitializeVM();
|
|
|
|
LocalContext context;
|
|
|
|
v8::HandleScope scope(context->GetIsolate());
|
|
|
|
|
|
|
|
CompileRun(
|
|
|
|
"function f(v) {"
|
|
|
|
" return {a: 0, b: v, c: 0};"
|
|
|
|
"}"
|
2019-03-25 15:05:47 +00:00
|
|
|
"%EnsureFeedbackVectorForFunction(f);"
|
2017-02-17 15:15:07 +00:00
|
|
|
"f(1);"
|
|
|
|
"f(2);"
|
|
|
|
"f(3);");
|
|
|
|
Handle<JSFunction> f = GetFunction("f");
|
|
|
|
// There should be one IC slot.
|
2018-06-23 09:05:50 +00:00
|
|
|
Handle<FeedbackVector> feedback_vector(f->feedback_vector(), f->GetIsolate());
|
2017-02-17 15:15:07 +00:00
|
|
|
FeedbackVectorHelper helper(feedback_vector);
|
|
|
|
CHECK_EQ(2, helper.slot_count());
|
|
|
|
CHECK_SLOT_KIND(helper, 0, FeedbackSlotKind::kLiteral);
|
[ic] name Set/Define/Store property operations more consistently
For background and reasoning, see
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit
This is the first step towards pulling the DefineNamedOwn operation out
of StoreIC.
Summary of the renamed identifiers:
Bytecodes:
- StaNamedProperty -> SetNamedProperty: calls StoreIC and emitted for
normal named property sets like obj.x = 1.
- StaNamedOwnProperty -> DefineNamedOwnProperty: calls
DefineNamedOwnIC (previously StoreOwnIC), and emitted for
initialization of named properties in object literals and named
public class fields.
- StaKeyedProperty -> SetKeyedProperty: calls KeyedStoreIC and emitted
for keyed property sets like obj[x] = 1.
- StaKeyedPropertyAsDefine -> DefineKeyedOwnProperty: calls
DefineKeyedOwnIC (previously KeyedDefineOwnIC) and emitted for
initialization of private class fields and computed public class
fields.
- StaDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral: calls
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral) and emitted for initialization of keyed
properties in object literals and static class initializers. (note
that previously the StoreDataPropertyInLiteral runtime function name
was taken by object spreads and array literal creation instead)
- LdaKeyedProperty -> GetKeyedProperty, LdaNamedProperty ->
GetNamedProperty, LdaNamedPropertyFromSuper ->
GetNamedPropertyFromSuper: we drop the Sta prefix for the property
store operations since the accumulator use is implicit and to make
the wording more natural, for symmetry the Lda prefix for the
property load operations is also dropped.
opcodes:
- (JS)StoreNamed -> (JS)SetNamedProperty: implements set semantics for
named properties, compiled from SetNamedProperty (previously
StaNamedProperty) and lowers to StoreIC or Runtime::kSetNamedProperty
- (JS)StoreNamedOwn -> (JS)DefineNamedOwnProperty: implements define
semantics for initializing named own properties in object literal and
public class fields, compiled from DefineNamedOwnProperty (previously
StaNamedOwnProperty) and lowers to DefineNamedOwnIC
(previously StoreOwnIC)
- (JS)StoreProperty -> (JS)SetKeyedProperty: implements set semantics
for keyed properties, only compiled from SetKeyedProperty(previously
StaKeyedProperty) and lowers to KeyedStoreIC
- (JS)DefineProperty -> (JS)DefineKeyedOwnProperty: implements define
semantics for initialization of private class fields and computed
public class fields, compiled from DefineKeyedOwnProperty (previously
StaKeyedPropertyAsDefine) and calls DefineKeyedOwnIC (previously
KeyedDefineOwnIC).
- (JS)StoreDataPropertyInLiteral ->
(JS)DefineKeyedOwnPropertyInLiteral: implements define semantics for
initialization of keyed properties in object literals and static
class initializers, compiled from DefineKeyedOwnPropertyInLiteral
(previously StaDataPropertyInLiteral) and calls the
DefineKeyedOwnPropertyInLiteral runtime function (previously
DefineDataPropertyInLiteral).
Runtime:
- DefineDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral:
following the bytecode/opcodes change, this is used by
DefineKeyedOwnPropertyInLiteral (previously StaDataPropertyInLiteral)
for object and class literal initialization.
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral_Simple:
it's just a simplified version of DefineDataPropertyInLiteral that
does not update feedback or perform function name configuration.
This is used by object spread and array literal creation. Since we
are renaming DefineDataPropertyInLiteral to
DefineKeyedOwnPropertyInLiteral, rename this simplified version with
a `_Simple` suffix. We can consider merging it into
DefineKeyedOwnPropertyInLiteral in the future. See
https://docs.google.com/document/d/1jvSEvXFHRkxg4JX-j6ho3nRqAF8vZI2Ai7RI8AY54gM/edit?disco=AAAAQQIz6mU
- Other changes following the bytecode/IR changes
IC:
- StoreOwn -> DefineNamedOwn: used for initialization of named
properties in object literals and named public class fields.
- StoreOwnIC -> DefineNamedOwnIC
- StoreMode::kStoreOwn -> StoreMode::kDefineNamedOwn
- StoreICMode::kStoreOwn -> StoreICMode::kDefineNamedOwn
- IsStoreOwn() -> IsDefineNamedOwn()
- DefineOwn -> DefineKeyedOwn: IsDefineOwnIC() was already just
IsDefineKeyedOwnIC(), and IsAnyDefineOwn() includes both named and
keyed defines so we don't need an extra generic predicate.
- StoreMode::kDefineOwn -> StoreMode::kDefineKeyedOwn
- StoreICMode::kDefineOwn -> StoreICMode::kDefineKeyedOwn
- IsDefineOwn() -> IsDefineKeyedOwn()
- IsDefineOwnIC() -> IsDefineKeyedOwnIC()
- Removing IsKeyedDefineOwnIC() as its now a duplicate of
IsDefineKeyedOwnIC()
- KeyedDefineOwnIC -> DefineKeyedOwnIC,
KeyedDefineOwnGenericGenerator() -> DefineKeyedOwnGenericGenerator:
make the ordering of terms more consistent
- IsAnyStoreOwn() -> IsAnyDefineOwn(): this includes the renamed and
DefineNamedOwn and DefineKeyedOwn. Also is_any_store_own() is
removed since it's just a duplicate of this.
- IsKeyedStoreOwn() -> IsDefineNamedOwn(): it's unclear where the
"keyed" part came from, but it's only used when DefineNamedOwnIC
(previously StoreOwnIC) reuses KeyedStoreIC, so rename it accordingly
Interpreter & compiler:
- BytecodeArrayBuilder: following bytecode changes
- StoreNamedProperty -> SetNamedProperty
- StoreNamedOwnProperty -> DefineNamedOwnProperty
- StoreKeyedProperty -> SetKeyedProperty
- DefineKeyedProperty -> DefineKeyedOwnProperty
- StoreDataPropertyInLiteral -> DefineKeyedOwnPropertyInLiteral
- FeedbackSlotKind:
- kDefineOwnKeyed -> kDefineKeyedOwn: make the ordering of terms more
consistent
- kStoreOwnNamed -> kDefineNamedOwn: following the IC change
- kStoreNamed{Sloppy|Strict} -> kSetNamed{Sloppy|Strict}: only
used in StoreIC for set semantics
- kStoreKeyed{Sloppy|Strict} -> kSetKeyed{Sloppy|Strict}: only used
in KeyedStoreIC for set semantics
- kStoreDataPropertyInLiteral -> kDefineKeyedOwnPropertyInLiteral:
following the IC change
- BytecodeGraphBuilder
- StoreMode::kNormal, kOwn -> NamedStoreMode::kSet, kDefineOwn: this
is only used by BytecodeGraphBuilder::BuildNamedStore() to tell the
difference between SetNamedProperty and DefineNamedOwnProperty
operations.
Not changed:
- StoreIC and KeyedStoreIC currently contain mixed logic for both Set
and Define operations, and the paths are controlled by feedback. The
plan is to refactor the hierarchy like this:
```
- StoreIC
- DefineNamedOwnIC
- SetNamedIC (there could also be a NamedStoreIC if that's helpful)
- KeyedStoreIC
- SetKeyedIC
- DefineKeyedOwnIC
- DefineKeyedOwnICLiteral (could be merged into DefineKeyedOwnIC)
- StoreInArrayLiteralIC
- ...
```
StoreIC and KeyedStoreIC would then contain helpers shared by their
subclasses, therefore it still makes sense to keep the word "Store"
in their names since they would be generic base classes for both set
and define operations.
- The Lda and Sta prefixes of bytecodes not involving object properties
(e.g. Ldar, Star, LdaZero) are kept, since this patch focuses on
property operations, and distinction between Set and Define might be
less relevant or nonexistent for bytecodes not involving object
properties. We could consider rename some of them in future patches
if that's helpful though.
Bug: v8:12548
Change-Id: Ia36997b02f59a87da3247f20e0560a7eb13077f3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3481475
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#79409}
2022-03-08 17:36:04 +00:00
|
|
|
CHECK_SLOT_KIND(helper, 1, FeedbackSlotKind::kDefineNamedOwn);
|
2018-01-31 13:51:30 +00:00
|
|
|
FeedbackNexus nexus(feedback_vector, helper.slot(1));
|
2021-11-19 18:02:26 +00:00
|
|
|
CHECK_EQ(InlineCacheState::MONOMORPHIC, nexus.ic_state());
|
2017-02-17 15:15:07 +00:00
|
|
|
}
|
|
|
|
|
2015-09-30 13:46:56 +00:00
|
|
|
} // namespace
|
2017-08-11 11:22:28 +00:00
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|