[turbofan] Add fast path for cached property names.
Port the fast path for accessor inlining to cached property names from Crankshaft to TurboFan. This constant-folds accesses to document in a script. R=jochen@chromium.org BUG=v8:5548 Review-Url: https://codereview.chromium.org/2646363003 Cr-Commit-Position: refs/heads/master@{#42600}
This commit is contained in:
parent
94266b7d86
commit
e347408d4d
@ -373,6 +373,17 @@ bool AccessInfoFactory::ComputePropertyAccessInfo(
|
||||
}
|
||||
if (V8_UNLIKELY(FLAG_runtime_stats)) return false;
|
||||
}
|
||||
if (access_mode == AccessMode::kLoad) {
|
||||
Handle<Name> cached_property_name;
|
||||
if (FunctionTemplateInfo::TryGetCachedPropertyName(isolate(),
|
||||
accessor)
|
||||
.ToHandle(&cached_property_name)) {
|
||||
if (ComputePropertyAccessInfo(map, cached_property_name,
|
||||
access_mode, access_info)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
*access_info = PropertyAccessInfo::AccessorConstant(
|
||||
MapList{receiver_map}, accessor, holder);
|
||||
return true;
|
||||
|
@ -62,6 +62,7 @@ FieldAccess ForPropertyCellValue(MachineRepresentation representation,
|
||||
kTaggedBase, PropertyCell::kValueOffset, name, map, type, r, kind};
|
||||
return access;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) {
|
||||
@ -85,6 +86,7 @@ Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) {
|
||||
// Lookup on the global object instead. We only deal with own data
|
||||
// properties of the global object here (represented as PropertyCell).
|
||||
LookupIterator it(global_object(), name, LookupIterator::OWN);
|
||||
it.TryLookupCachedProperty();
|
||||
if (it.state() != LookupIterator::DATA) return NoChange();
|
||||
if (!it.GetHolder<JSObject>()->IsJSGlobalObject()) return NoChange();
|
||||
Handle<PropertyCell> property_cell = it.GetPropertyCell();
|
||||
|
@ -349,9 +349,6 @@
|
||||
['variant == turbofan or variant == ignition_turbofan', {
|
||||
# BUG(4751). Flaky with Ignition.
|
||||
'test-cpu-profiler/JsNativeJsSample': [SKIP],
|
||||
|
||||
# TODO(vogelheim,5548): Turbofan does support cached accessors.
|
||||
'test-api-accessors/CachedAccessorCrankshaft': [FAIL],
|
||||
}], # variant == turbofan or variant == ignition_turbofan
|
||||
|
||||
##############################################################################
|
||||
|
@ -249,6 +249,89 @@ TEST(CachedAccessorCrankshaft) {
|
||||
ExpectInt32("g()", 789);
|
||||
}
|
||||
|
||||
TEST(CachedAccessorOnGlobalObject) {
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
LocalContext env;
|
||||
v8::Isolate* isolate = env->GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
v8::Local<v8::FunctionTemplate> templ =
|
||||
v8::FunctionTemplate::New(CcTest::isolate());
|
||||
v8::Local<v8::ObjectTemplate> object_template = templ->InstanceTemplate();
|
||||
v8::Local<v8::Private> priv =
|
||||
v8::Private::ForApi(isolate, v8_str("Foo#draft"));
|
||||
|
||||
object_template->SetAccessorProperty(
|
||||
v8_str("draft"),
|
||||
v8::FunctionTemplate::NewWithCache(isolate, UnreachableCallback, priv,
|
||||
v8::Local<v8::Value>()));
|
||||
|
||||
v8::Local<v8::Context> ctx =
|
||||
v8::Context::New(CcTest::isolate(), nullptr, object_template);
|
||||
v8::Local<v8::Object> obj = ctx->Global();
|
||||
|
||||
// Install the private property on the instance.
|
||||
CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv,
|
||||
v8::Undefined(isolate))
|
||||
.FromJust());
|
||||
|
||||
{
|
||||
v8::Context::Scope context_scope(ctx);
|
||||
|
||||
// Access surrogate accessor.
|
||||
ExpectUndefined("draft");
|
||||
|
||||
// Set hidden property.
|
||||
CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 123))
|
||||
.FromJust());
|
||||
|
||||
// Test ICs.
|
||||
CompileRun(
|
||||
"function f() {"
|
||||
" var x;"
|
||||
" for (var i = 0; i < 100; i++) {"
|
||||
" x = draft;"
|
||||
" }"
|
||||
" return x;"
|
||||
"}");
|
||||
|
||||
ExpectInt32("f()", 123);
|
||||
|
||||
// Reset hidden property.
|
||||
CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
|
||||
.FromJust());
|
||||
|
||||
// Test Crankshaft.
|
||||
CompileRun("%OptimizeFunctionOnNextCall(f);");
|
||||
|
||||
ExpectInt32("f()", 456);
|
||||
|
||||
CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456))
|
||||
.FromJust());
|
||||
// Test non-global ICs.
|
||||
CompileRun(
|
||||
"var x = this;"
|
||||
"function g() {"
|
||||
" var r = 0;"
|
||||
" for (var i = 0; i < 100; i++) {"
|
||||
" r = x.draft;"
|
||||
" }"
|
||||
" return r;"
|
||||
"}");
|
||||
|
||||
ExpectInt32("g()", 456);
|
||||
|
||||
// Reset hidden property.
|
||||
CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 789))
|
||||
.FromJust());
|
||||
|
||||
// Test non-global access in Crankshaft.
|
||||
CompileRun("%OptimizeFunctionOnNextCall(g);");
|
||||
|
||||
ExpectInt32("g()", 789);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
static void Setter(v8::Local<v8::String> name, v8::Local<v8::Value> value,
|
||||
|
Loading…
Reference in New Issue
Block a user