Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Unified Diff: src/compiler/access-info.cc

Issue 1418213010: [turbofan] Initial support for keyed access to fast JSArrays. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/access-info.h ('k') | src/compiler/js-native-context-specialization.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/access-info.cc
diff --git a/src/compiler/property-access-info.cc b/src/compiler/access-info.cc
similarity index 80%
rename from src/compiler/property-access-info.cc
rename to src/compiler/access-info.cc
index 930098ac8c305733841a02008c6afceb1f80e5e0..1603804d8e8f1d65d001f1839524dcfcd3ef90ea 100644
--- a/src/compiler/property-access-info.cc
+++ b/src/compiler/access-info.cc
@@ -6,7 +6,7 @@
#include "src/accessors.h"
#include "src/compilation-dependencies.h"
-#include "src/compiler/property-access-info.h"
+#include "src/compiler/access-info.h"
#include "src/field-index-inl.h"
#include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker!
#include "src/type-cache.h"
@@ -16,11 +16,35 @@ namespace v8 {
namespace internal {
namespace compiler {
-std::ostream& operator<<(std::ostream& os, PropertyAccessMode access_mode) {
+namespace {
+
+bool CanInlineElementAccess(Handle<Map> map) {
+ // TODO(bmeurer): IsJSObjectMap
+ // TODO(bmeurer): !map->has_dictionary_elements()
+ // TODO(bmeurer): !map->has_sloppy_arguments_elements()
+ return map->IsJSArrayMap() && map->has_fast_elements() &&
+ !map->has_indexed_interceptor() && !map->is_access_check_needed();
+}
+
+
+bool CanInlinePropertyAccess(Handle<Map> map) {
+ // TODO(bmeurer): Add support for Number primitives.
+ // if (map->instance_type() == HEAP_NUMBER_TYPE) return false;
+ if (map->instance_type() < FIRST_NONSTRING_TYPE) return true;
+ return map->IsJSObjectMap() && !map->is_dictionary_map() &&
+ !map->has_named_interceptor() &&
+ // TODO(verwaest): Whitelist contexts to which we have access.
+ !map->is_access_check_needed();
+}
+
+} // namespace
+
+
+std::ostream& operator<<(std::ostream& os, AccessMode access_mode) {
switch (access_mode) {
- case PropertyAccessMode::kLoad:
+ case AccessMode::kLoad:
return os << "Load";
- case PropertyAccessMode::kStore:
+ case AccessMode::kStore:
return os << "Store";
}
UNREACHABLE();
@@ -52,6 +76,9 @@ PropertyAccessInfo PropertyAccessInfo::DataField(
}
+ElementAccessInfo::ElementAccessInfo() : receiver_type_(Type::None()) {}
+
+
PropertyAccessInfo::PropertyAccessInfo()
: kind_(kInvalid), receiver_type_(Type::None()), field_type_(Type::Any()) {}
@@ -86,9 +113,8 @@ PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
field_type_(field_type) {}
-PropertyAccessInfoFactory::PropertyAccessInfoFactory(
- CompilationDependencies* dependencies, Handle<Context> native_context,
- Zone* zone)
+AccessInfoFactory::AccessInfoFactory(CompilationDependencies* dependencies,
+ Handle<Context> native_context, Zone* zone)
: dependencies_(dependencies),
native_context_(native_context),
isolate_(native_context->GetIsolate()),
@@ -96,23 +122,52 @@ PropertyAccessInfoFactory::PropertyAccessInfoFactory(
zone_(zone) {}
-namespace {
+bool AccessInfoFactory::ComputeElementAccessInfo(
+ Handle<Map> map, AccessMode access_mode, ElementAccessInfo* access_info) {
+ // Check if it is safe to inline element access for the {map}.
+ if (!CanInlineElementAccess(map)) return false;
-bool CanInlinePropertyAccess(Handle<Map> map) {
- // TODO(bmeurer): Do something about the number stuff.
- if (map->instance_type() == HEAP_NUMBER_TYPE) return false;
- if (map->instance_type() < FIRST_NONSTRING_TYPE) return true;
- return map->IsJSObjectMap() && !map->is_dictionary_map() &&
- !map->has_named_interceptor() &&
- // TODO(verwaest): Whitelist contexts to which we have access.
- !map->is_access_check_needed();
+ // TODO(bmeurer): Add support for holey elements.
+ ElementsKind elements_kind = map->elements_kind();
+ if (IsHoleyElementsKind(elements_kind)) return false;
+
+ // Certain (monomorphic) stores need a prototype chain check because shape
+ // changes could allow callbacks on elements in the chain that are not
+ // compatible with monomorphic keyed stores.
+ MaybeHandle<JSObject> holder;
+ if (access_mode == AccessMode::kStore && map->prototype()->IsJSObject()) {
+ for (PrototypeIterator i(map); !i.IsAtEnd(); i.Advance()) {
+ Handle<JSReceiver> prototype =
+ PrototypeIterator::GetCurrent<JSReceiver>(i);
+ if (!prototype->IsJSObject()) return false;
+ holder = Handle<JSObject>::cast(prototype);
+ }
+ }
+
+ *access_info =
+ ElementAccessInfo(Type::Class(map, zone()), elements_kind, holder);
+ return true;
}
-} // namespace
+
+bool AccessInfoFactory::ComputeElementAccessInfos(
+ MapHandleList const& maps, AccessMode access_mode,
+ ZoneVector<ElementAccessInfo>* access_infos) {
+ for (Handle<Map> map : maps) {
+ if (Map::TryUpdate(map).ToHandle(&map)) {
+ ElementAccessInfo access_info;
+ if (!ComputeElementAccessInfo(map, access_mode, &access_info)) {
+ return false;
+ }
+ access_infos->push_back(access_info);
+ }
+ }
+ return true;
+}
-bool PropertyAccessInfoFactory::ComputePropertyAccessInfo(
- Handle<Map> map, Handle<Name> name, PropertyAccessMode access_mode,
+bool AccessInfoFactory::ComputePropertyAccessInfo(
+ Handle<Map> map, Handle<Name> name, AccessMode access_mode,
PropertyAccessInfo* access_info) {
// Check if it is safe to inline property access for the {map}.
if (!CanInlinePropertyAccess(map)) return false;
@@ -121,7 +176,7 @@ bool PropertyAccessInfoFactory::ComputePropertyAccessInfo(
Handle<Map> receiver_map = map;
// We support fast inline cases for certain JSObject getters.
- if (access_mode == PropertyAccessMode::kLoad &&
+ if (access_mode == AccessMode::kLoad &&
LookupSpecialFieldAccessor(map, name, access_info)) {
return true;
}
@@ -133,7 +188,7 @@ bool PropertyAccessInfoFactory::ComputePropertyAccessInfo(
int const number = descriptors->SearchWithCache(*name, *map);
if (number != DescriptorArray::kNotFound) {
PropertyDetails const details = descriptors->GetDetails(number);
- if (access_mode == PropertyAccessMode::kStore) {
+ if (access_mode == AccessMode::kStore) {
// Don't bother optimizing stores to read-only properties.
if (details.IsReadOnly()) {
return false;
@@ -170,7 +225,7 @@ bool PropertyAccessInfoFactory::ComputePropertyAccessInfo(
Type::TaggedPointer(), zone());
if (field_type->Is(Type::None())) {
// Store is not safe if the field type was cleared.
- if (access_mode == PropertyAccessMode::kStore) return false;
+ if (access_mode == AccessMode::kStore) return false;
// The field type was cleared by the GC, so we don't know anything
// about the contents now.
@@ -216,7 +271,7 @@ bool PropertyAccessInfoFactory::ComputePropertyAccessInfo(
// Store to property not found on the receiver or any prototype, we need
// to transition to a new data property.
// Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver)
- if (access_mode == PropertyAccessMode::kStore) {
+ if (access_mode == AccessMode::kStore) {
return LookupTransition(receiver_map, name, holder, access_info);
}
// The property was not found, return undefined or throw depending
@@ -242,9 +297,8 @@ bool PropertyAccessInfoFactory::ComputePropertyAccessInfo(
}
-bool PropertyAccessInfoFactory::ComputePropertyAccessInfos(
- MapHandleList const& maps, Handle<Name> name,
- PropertyAccessMode access_mode,
+bool AccessInfoFactory::ComputePropertyAccessInfos(
+ MapHandleList const& maps, Handle<Name> name, AccessMode access_mode,
ZoneVector<PropertyAccessInfo>* access_infos) {
for (Handle<Map> map : maps) {
if (Map::TryUpdate(map).ToHandle(&map)) {
@@ -259,7 +313,7 @@ bool PropertyAccessInfoFactory::ComputePropertyAccessInfos(
}
-bool PropertyAccessInfoFactory::LookupSpecialFieldAccessor(
+bool AccessInfoFactory::LookupSpecialFieldAccessor(
Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) {
// Check for special JSObject field accessors.
int offset;
@@ -294,9 +348,9 @@ bool PropertyAccessInfoFactory::LookupSpecialFieldAccessor(
}
-bool PropertyAccessInfoFactory::LookupTransition(
- Handle<Map> map, Handle<Name> name, MaybeHandle<JSObject> holder,
- PropertyAccessInfo* access_info) {
+bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name,
+ MaybeHandle<JSObject> holder,
+ PropertyAccessInfo* access_info) {
// Check if the {map} has a data transition with the given {name}.
if (map->unused_property_fields() == 0) return false;
Handle<Map> transition_map;
@@ -349,9 +403,7 @@ bool PropertyAccessInfoFactory::LookupTransition(
}
-Factory* PropertyAccessInfoFactory::factory() const {
- return isolate()->factory();
-}
+Factory* AccessInfoFactory::factory() const { return isolate()->factory(); }
} // namespace compiler
} // namespace internal
« no previous file with comments | « src/compiler/access-info.h ('k') | src/compiler/js-native-context-specialization.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698