Commit c9308147 authored by jkummerow's avatar jkummerow Committed by Commit bot

[KeyedLoadIC] Support Smi "handlers" for element loads

This is an experiment as far as performance is concerned. If Smi-configured
element loading directly from the dispatcher stub is fast enough, then we
can stop compiling LoadFastElementStubs (and drop the corresponding code).

Review-Url: https://codereview.chromium.org/2180273002
Cr-Commit-Position: refs/heads/master@{#38377}
parent d3d7069d
This diff is collapsed.
......@@ -509,9 +509,6 @@ class CodeStubAssembler : public compiler::CodeAssembler {
Variable* var_handler, Label* if_miss,
int unroll_count);
void HandleLoadICHandlerCase(const LoadICParameters* p,
compiler::Node* handler, Label* miss);
compiler::Node* StubCachePrimaryOffset(compiler::Node* name,
compiler::Node* map);
......@@ -552,6 +549,19 @@ class CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* value);
private:
enum ElementSupport { kOnlyProperties, kSupportElements };
void HandleLoadICHandlerCase(
const LoadICParameters* p, compiler::Node* handler, Label* miss,
ElementSupport support_elements = kOnlyProperties);
void EmitBoundsCheck(compiler::Node* object, compiler::Node* elements,
compiler::Node* intptr_key, compiler::Node* is_jsarray,
Label* miss);
void EmitElementLoad(compiler::Node* object, compiler::Node* elements,
compiler::Node* elements_kind, compiler::Node* key,
Label* if_hole, Label* rebox_double,
Variable* var_double_value, Label* miss);
compiler::Node* ElementOffsetFromIndex(compiler::Node* index,
ElementsKind kind, ParameterMode mode,
int base_size = 0);
......
......@@ -6,6 +6,7 @@
#define V8_FIELD_INDEX_INL_H_
#include "src/field-index.h"
#include "src/ic/handler-configuration.h"
namespace v8 {
namespace internal {
......@@ -88,7 +89,7 @@ inline int FieldIndex::GetLoadByFieldIndex() const {
// FieldIndex object from it.
// static
inline FieldIndex FieldIndex::ForLoadByFieldOffset(Map* map, int offset) {
DCHECK(offset & 1); // Property marker (as opposed to element).
DCHECK(LoadHandlerTypeBit::decode(offset) == kLoadICHandlerForProperties);
bool is_inobject = FieldOffsetIsInobject::decode(offset);
bool is_double = FieldOffsetIsDouble::decode(offset);
int field_index = FieldOffsetOffset::decode(offset) >> kPointerSizeLog2;
......@@ -114,7 +115,7 @@ inline int FieldIndex::GetLoadByFieldOffset() const {
return FieldOffsetIsInobject::encode(is_inobject()) |
FieldOffsetIsDouble::encode(is_double()) |
FieldOffsetOffset::encode(index() << kPointerSizeLog2) |
1; // Property marker (as opposed to element).
LoadHandlerTypeBit::encode(kLoadICHandlerForProperties);
}
inline FieldIndex FieldIndex::ForDescriptor(Map* map, int descriptor_index) {
......
......@@ -81,13 +81,6 @@ class FieldIndex final {
}
bool operator!=(FieldIndex const& other) const { return !(*this == other); }
// For GetLoadByFieldOffset.
class FieldOffsetIsInobject : public BitField<bool, 1, 1> {};
class FieldOffsetIsDouble : public BitField<bool, 2, 1> {};
class FieldOffsetOffset : public BitField<int, 3, 27> {};
// Make sure we don't overflow into the sign bit.
STATIC_ASSERT(FieldOffsetOffset::kNext <= kSmiValueSize - 1);
private:
FieldIndex(bool is_inobject, int local_index, bool is_double,
int inobject_properties, int first_inobject_property_offset,
......
......@@ -6,6 +6,7 @@
#include "src/field-type.h"
#include "src/ic/call-optimization.h"
#include "src/ic/handler-configuration.h"
#include "src/ic/ic-inl.h"
#include "src/ic/ic.h"
#include "src/isolate-inl.h"
......@@ -577,7 +578,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
#undef __
// static
Handle<Code> ElementHandlerCompiler::GetKeyedLoadHandler(
Handle<Object> ElementHandlerCompiler::GetKeyedLoadHandler(
Handle<Map> receiver_map, Isolate* isolate) {
if (receiver_map->has_indexed_interceptor() &&
!receiver_map->GetIndexedInterceptor()->getter()->IsUndefined(isolate) &&
......@@ -610,10 +611,18 @@ Handle<Code> ElementHandlerCompiler::GetKeyedLoadHandler(
bool convert_hole_to_undefined =
is_js_array && elements_kind == FAST_HOLEY_ELEMENTS &&
*receiver_map == isolate->get_initial_js_array_map(elements_kind);
TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadFastElementStub);
return LoadFastElementStub(isolate, is_js_array, elements_kind,
convert_hole_to_undefined)
.GetCode();
if (FLAG_tf_load_ic_stub) {
int config = KeyedLoadElementsKind::encode(elements_kind) |
KeyedLoadConvertHole::encode(convert_hole_to_undefined) |
KeyedLoadIsJsArray::encode(is_js_array) |
LoadHandlerTypeBit::encode(kLoadICHandlerForElements);
return handle(Smi::FromInt(config), isolate);
} else {
TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadFastElementStub);
return LoadFastElementStub(isolate, is_js_array, elements_kind,
convert_hole_to_undefined)
.GetCode();
}
}
void ElementHandlerCompiler::CompileElementHandlers(
......
......@@ -279,8 +279,8 @@ class ElementHandlerCompiler : public PropertyHandlerCompiler {
virtual ~ElementHandlerCompiler() {}
static Handle<Code> GetKeyedLoadHandler(Handle<Map> receiver_map,
Isolate* isolate);
static Handle<Object> GetKeyedLoadHandler(Handle<Map> receiver_map,
Isolate* isolate);
void CompileElementHandlers(MapHandleList* receiver_maps,
List<Handle<Object>>* handlers);
......
// Copyright 2016 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.
#ifndef V8_IC_HANDLER_CONFIGURATION_H_
#define V8_IC_HANDLER_CONFIGURATION_H_
#include "src/elements-kind.h"
#include "src/globals.h"
#include "src/utils.h"
namespace v8 {
namespace internal {
enum LoadHandlerType {
kLoadICHandlerForElements = 0,
kLoadICHandlerForProperties = 1
};
class LoadHandlerTypeBit : public BitField<bool, 0, 1> {};
// Encoding for configuration Smis for property loads:
class FieldOffsetIsInobject
: public BitField<bool, LoadHandlerTypeBit::kNext, 1> {};
class FieldOffsetIsDouble
: public BitField<bool, FieldOffsetIsInobject::kNext, 1> {};
class FieldOffsetOffset : public BitField<int, FieldOffsetIsDouble::kNext, 27> {
};
// Make sure we don't overflow into the sign bit.
STATIC_ASSERT(FieldOffsetOffset::kNext <= kSmiValueSize - 1);
// Encoding for configuration Smis for elements loads:
class KeyedLoadIsJsArray : public BitField<bool, LoadHandlerTypeBit::kNext, 1> {
};
class KeyedLoadConvertHole
: public BitField<bool, KeyedLoadIsJsArray::kNext, 1> {};
class KeyedLoadElementsKind
: public BitField<ElementsKind, KeyedLoadConvertHole::kNext, 8> {};
// Make sure we don't overflow into the sign bit.
STATIC_ASSERT(KeyedLoadElementsKind::kNext <= kSmiValueSize - 1);
} // namespace internal
} // namespace v8
#endif // V8_IC_HANDLER_CONFIGURATION_H_
......@@ -1328,7 +1328,7 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) {
TargetMaps(&target_receiver_maps);
if (target_receiver_maps.length() == 0) {
Handle<Code> handler =
Handle<Object> handler =
ElementHandlerCompiler::GetKeyedLoadHandler(receiver_map, isolate());
return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
}
......@@ -1357,7 +1357,7 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) {
IsMoreGeneralElementsKindTransition(
target_receiver_maps.at(0)->elements_kind(),
Handle<JSObject>::cast(receiver)->GetElementsKind())) {
Handle<Code> handler =
Handle<Object> handler =
ElementHandlerCompiler::GetKeyedLoadHandler(receiver_map, isolate());
return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment