Commit 119cb566 authored by verwaest's avatar verwaest Committed by Commit bot

Stop using HeapType in IC and Crankshaft

BUG=

Review URL: https://codereview.chromium.org/935603002

Cr-Commit-Position: refs/heads/master@{#26696}
parent 0a4047a6
......@@ -69,20 +69,10 @@ static V8_INLINE bool CheckForName(Handle<Name> name,
// Returns true for properties that are accessors to object fields.
// If true, *object_offset contains offset of object field.
template <class T>
bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type,
Handle<Name> name,
bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
int* object_offset) {
Isolate* isolate = name->GetIsolate();
if (type->Is(T::String())) {
return CheckForName(name, isolate->factory()->length_string(),
String::kLengthOffset, object_offset);
}
if (!type->IsClass()) return false;
Handle<Map> map = type->AsClass()->Map();
switch (map->instance_type()) {
case JS_ARRAY_TYPE:
return
......@@ -107,23 +97,16 @@ bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type,
CheckForName(name, isolate->factory()->byte_offset_string(),
JSDataView::kByteOffsetOffset, object_offset);
default:
if (map->instance_type() < FIRST_NONSTRING_TYPE) {
return CheckForName(name, isolate->factory()->length_string(),
String::kLengthOffset, object_offset);
}
return false;
}
}
template
bool Accessors::IsJSObjectFieldAccessor<Type>(Type* type,
Handle<Name> name,
int* object_offset);
template
bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type,
Handle<Name> name,
int* object_offset);
bool SetPropertyOnInstanceIfInherited(
Isolate* isolate, const v8::PropertyCallbackInfo<void>& info,
v8::Local<v8::Name> name, Handle<Object> value) {
......
......@@ -78,9 +78,7 @@ class Accessors : public AllStatic {
// Returns true for properties that are accessors to object fields.
// If true, *object_offset contains offset of object field.
template <class T>
static bool IsJSObjectFieldAccessor(typename T::TypeHandle type,
Handle<Name> name,
static bool IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
int* object_offset);
static Handle<AccessorInfo> MakeAccessor(
......
This diff is collapsed.
......@@ -2282,8 +2282,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
Type* ToType(Handle<Map> map);
private:
// Helpers for flow graph construction.
enum GlobalPropertyAccess {
......@@ -2434,16 +2432,15 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
class PropertyAccessInfo {
public:
PropertyAccessInfo(HOptimizedGraphBuilder* builder,
PropertyAccessType access_type,
Type* type,
PropertyAccessType access_type, Handle<Map> map,
Handle<String> name)
: lookup_(builder->isolate()),
builder_(builder),
access_type_(access_type),
type_(type),
map_(map),
name_(name),
field_type_(HType::Tagged()),
access_(HObjectAccess::ForMap()) { }
access_(HObjectAccess::ForMap()) {}
// Checkes whether this PropertyAccessInfo can be handled as a monomorphic
// load named. It additionally fills in the fields necessary to generate the
......@@ -2458,22 +2455,23 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
// PropertyAccessInfo is built for types->first().
bool CanAccessAsMonomorphic(SmallMapList* types);
bool NeedsWrappingFor(Handle<JSFunction> target) const;
Handle<Map> map();
Type* type() const { return type_; }
Handle<String> name() const { return name_; }
bool IsJSObjectFieldAccessor() {
int offset; // unused
return Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset);
return Accessors::IsJSObjectFieldAccessor(map(), name_, &offset);
}
bool GetJSObjectFieldAccess(HObjectAccess* access) {
int offset;
if (Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset)) {
if (type_->Is(Type::String())) {
if (Accessors::IsJSObjectFieldAccessor(map(), name_, &offset)) {
if (IsStringType()) {
DCHECK(String::Equals(isolate()->factory()->length_string(), name_));
*access = HObjectAccess::ForStringLength();
} else if (type_->Is(Type::Array())) {
} else if (IsArrayType()) {
DCHECK(String::Equals(isolate()->factory()->length_string(), name_));
*access = HObjectAccess::ForArrayLength(map()->elements_kind());
} else {
......@@ -2506,6 +2504,11 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
bool IsConfigurable() const { return lookup_.IsConfigurable(); }
bool IsReadOnly() const { return lookup_.IsReadOnly(); }
bool IsStringType() { return map_->instance_type() < FIRST_NONSTRING_TYPE; }
bool IsNumberType() { return map_->instance_type() == HEAP_NUMBER_TYPE; }
bool IsValueWrapped() { return IsStringType() || IsNumberType(); }
bool IsArrayType() { return map_->instance_type() == JS_ARRAY_TYPE; }
private:
Handle<Object> GetAccessorsFromMap(Handle<Map> map) const {
return handle(lookup_.GetValueFromMap(*map), isolate());
......@@ -2524,7 +2527,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
}
Representation representation() const { return lookup_.representation(); }
Type* ToType(Handle<Map> map) { return builder_->ToType(map); }
Zone* zone() { return builder_->zone(); }
CompilationInfo* top_info() { return builder_->top_info(); }
CompilationInfo* current_info() { return builder_->current_info(); }
......@@ -2543,7 +2545,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
LookupResult lookup_;
HOptimizedGraphBuilder* builder_;
PropertyAccessType access_type_;
Type* type_;
Handle<Map> map_;
Handle<String> name_;
Handle<JSObject> holder_;
Handle<JSFunction> accessor_;
......
......@@ -17,9 +17,8 @@ namespace internal {
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<HeapType> type, Register receiver,
Register holder, int accessor_index, int expected_arguments,
Register scratch) {
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
// ----------- S t a t e -------------
// -- r0 : receiver
// -- r2 : name
......@@ -32,7 +31,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
DCHECK(!holder.is(scratch));
DCHECK(!receiver.is(scratch));
// Call the JavaScript getter with the receiver on the stack.
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
if (map->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
__ ldr(scratch,
FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
......@@ -57,9 +56,8 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
MacroAssembler* masm, Handle<HeapType> type, Register receiver,
Register holder, int accessor_index, int expected_arguments,
Register scratch) {
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
// ----------- S t a t e -------------
// -- lr : return address
// -----------------------------------
......@@ -74,7 +72,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
DCHECK(!receiver.is(scratch));
DCHECK(!value().is(scratch));
// Call the JavaScript setter with receiver and value on the stack.
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
if (map->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
__ ldr(scratch,
FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
......@@ -415,7 +413,7 @@ Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss,
PrototypeCheckType check) {
Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
Handle<Map> receiver_map = map();
// Make sure there's no overlap between holder and object registers.
DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
......@@ -427,8 +425,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
if (type()->IsConstant()) {
current = Handle<JSObject>::cast(type()->AsConstant()->Value());
if (receiver_map->IsJSGlobalObjectMap()) {
current = isolate()->global_object();
}
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
......
......@@ -32,7 +32,7 @@ void PropertyICCompiler::GenerateRuntimeSetProperty(
#define __ ACCESS_MASM(masm())
Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
Handle<Code> PropertyICCompiler::CompilePolymorphic(MapHandleList* maps,
CodeHandleList* handlers,
Handle<Name> name,
Code::StubType type,
......@@ -59,7 +59,7 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
}
Label number_case;
Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
Label* smi_target = IncludesNumberMap(maps) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
// Polymorphic keyed stores may use the map register
......@@ -67,17 +67,16 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
DCHECK(kind() != Code::KEYED_STORE_IC ||
map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister()));
int receiver_count = types->length();
int receiver_count = maps->length();
int number_of_handled_maps = 0;
__ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
for (int current = 0; current < receiver_count; ++current) {
Handle<HeapType> type = types->at(current);
Handle<Map> map = IC::TypeToMap(*type, isolate());
Handle<Map> map = maps->at(current);
if (!map->is_deprecated()) {
number_of_handled_maps++;
Handle<WeakCell> cell = Map::WeakCellForMap(map);
__ CmpWeakValue(map_reg, cell, scratch2());
if (type->Is(HeapType::Number())) {
if (map->instance_type() == HEAP_NUMBER_TYPE) {
DCHECK(!number_case.is_unused());
__ bind(&number_case);
}
......
......@@ -223,9 +223,8 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
MacroAssembler* masm, Handle<HeapType> type, Register receiver,
Register holder, int accessor_index, int expected_arguments,
Register scratch) {
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
// ----------- S t a t e -------------
// -- lr : return address
// -----------------------------------
......@@ -241,7 +240,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
DCHECK(!AreAliased(receiver, scratch));
DCHECK(!AreAliased(value(), scratch));
// Call the JavaScript setter with receiver and value on the stack.
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
if (map->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
__ Ldr(scratch,
FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
......@@ -269,9 +268,8 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<HeapType> type, Register receiver,
Register holder, int accessor_index, int expected_arguments,
Register scratch) {
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
......@@ -279,7 +277,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
DCHECK(!AreAliased(holder, scratch));
DCHECK(!AreAliased(receiver, scratch));
// Call the JavaScript getter with the receiver on the stack.
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
if (map->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
__ Ldr(scratch,
FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
......@@ -465,7 +463,7 @@ Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss,
PrototypeCheckType check) {
Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
Handle<Map> receiver_map = map();
// object_reg and holder_reg registers can alias.
DCHECK(!AreAliased(object_reg, scratch1, scratch2));
......@@ -476,8 +474,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
if (type()->IsConstant()) {
current = Handle<JSObject>::cast(type()->AsConstant()->Value());
if (receiver_map->IsJSGlobalObjectMap()) {
current = isolate()->global_object();
}
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
......
......@@ -33,7 +33,7 @@ void PropertyICCompiler::GenerateRuntimeSetProperty(
#define __ ACCESS_MASM(masm())
Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
Handle<Code> PropertyICCompiler::CompilePolymorphic(MapHandleList* maps,
CodeHandleList* handlers,
Handle<Name> name,
Code::StubType type,
......@@ -59,7 +59,7 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
}
Label number_case;
Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
Label* smi_target = IncludesNumberMap(maps) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
// Polymorphic keyed stores may use the map register
......@@ -67,18 +67,17 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
DCHECK(kind() != Code::KEYED_STORE_IC ||
map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister()));
__ Ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
int receiver_count = types->length();
int receiver_count = maps->length();
int number_of_handled_maps = 0;
for (int current = 0; current < receiver_count; ++current) {
Handle<HeapType> type = types->at(current);
Handle<Map> map = IC::TypeToMap(*type, isolate());
Handle<Map> map = maps->at(current);
if (!map->is_deprecated()) {
number_of_handled_maps++;
Handle<WeakCell> cell = Map::WeakCellForMap(map);
__ CmpWeakValue(map_reg, cell, scratch2());
Label try_next;
__ B(ne, &try_next);
if (type->Is(HeapType::Number())) {
if (map->instance_type() == HEAP_NUMBER_TYPE) {
DCHECK(!number_case.is_unused());
__ Bind(&number_case);
}
......
......@@ -51,12 +51,12 @@ bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver,
DCHECK(is_simple_api_call());
if (!receiver->IsHeapObject()) return false;
Handle<Map> map(HeapObject::cast(*receiver)->map());
return IsCompatibleReceiverType(map, holder);
return IsCompatibleReceiverMap(map, holder);
}
bool CallOptimization::IsCompatibleReceiverType(Handle<Map> map,
Handle<JSObject> holder) const {
bool CallOptimization::IsCompatibleReceiverMap(Handle<Map> map,
Handle<JSObject> holder) const {
HolderLookup holder_lookup;
Handle<JSObject> api_holder = LookupHolderOfExpectedType(map, &holder_lookup);
switch (holder_lookup) {
......
......@@ -46,8 +46,8 @@ class CallOptimization BASE_EMBEDDED {
Handle<JSObject> holder) const;
// Check if the api holder is between the receiver and the holder.
bool IsCompatibleReceiverType(Handle<Map> receiver_map,
Handle<JSObject> holder) const;
bool IsCompatibleReceiverMap(Handle<Map> receiver_map,
Handle<JSObject> holder) const;
private:
void Initialize(Handle<JSFunction> function);
......
......@@ -26,9 +26,8 @@ Handle<Code> PropertyHandlerCompiler::Find(Handle<Name> name,
Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
Handle<Name> name, Handle<HeapType> type) {
Handle<Name> name, Handle<Map> receiver_map) {
Isolate* isolate = name->GetIsolate();
Handle<Map> receiver_map = IC::TypeToMap(*type, isolate);
if (receiver_map->prototype()->IsNull()) {
// TODO(jkummerow/verwaest): If there is no prototype and the property
// is nonexistent, introduce a builtin to handle this (fast properties
......@@ -37,7 +36,7 @@ Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
}
CacheHolderFlag flag;
Handle<Map> stub_holder_map =
IC::GetHandlerCacheHolder(*type, false, isolate, &flag);
IC::GetHandlerCacheHolder(receiver_map, false, isolate, &flag);
// If no dictionary mode objects are present in the prototype chain, the load
// nonexistent IC stub can be shared for all names for a given map and we use
......@@ -62,7 +61,7 @@ Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST);
if (!handler.is_null()) return handler;
NamedLoadHandlerCompiler compiler(isolate, type, last, flag);
NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag);
handler = compiler.CompileLoadNonexistent(cache_name);
Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
return handler;
......@@ -82,11 +81,6 @@ Handle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind,
}
void PropertyHandlerCompiler::set_type_for_object(Handle<Object> object) {
type_ = IC::CurrentTypeOf(object, isolate());
}
#define __ ACCESS_MASM(masm())
......@@ -95,13 +89,13 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
Label* miss) {
PrototypeCheckType check_type = CHECK_ALL_MAPS;
int function_index = -1;
if (type()->Is(HeapType::String())) {
if (map()->instance_type() < FIRST_NONSTRING_TYPE) {
function_index = Context::STRING_FUNCTION_INDEX;
} else if (type()->Is(HeapType::Symbol())) {
} else if (map()->instance_type() == SYMBOL_TYPE) {
function_index = Context::SYMBOL_FUNCTION_INDEX;
} else if (type()->Is(HeapType::Number())) {
} else if (map()->instance_type() == HEAP_NUMBER_TYPE) {
function_index = Context::NUMBER_FUNCTION_INDEX;
} else if (type()->Is(HeapType::Boolean())) {
} else if (*map() == isolate()->heap()->boolean_map()) {
function_index = Context::BOOLEAN_FUNCTION_INDEX;
} else {
check_type = SKIP_RECEIVER;
......@@ -112,7 +106,8 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
scratch1(), miss);
Object* function = isolate()->native_context()->get(function_index);
Object* prototype = JSFunction::cast(function)->instance_prototype();
set_type_for_object(handle(prototype, isolate()));
Handle<Map> map(JSObject::cast(prototype)->map());
set_map(map);
object_reg = scratch1();
}
......@@ -155,7 +150,7 @@ void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name,
Handle<Map> last_map;
if (holder().is_null()) {
holder_reg = receiver();
last_map = IC::TypeToMap(*type(), isolate());
last_map = map();
// If |type| has null as its prototype, |holder()| is
// Handle<JSObject>::null().
DCHECK(last_map->prototype() == isolate()->heap()->null_value());
......@@ -168,7 +163,7 @@ void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name,
if (last_map->IsJSGlobalObjectMap()) {
Handle<JSGlobalObject> global =
holder().is_null()
? Handle<JSGlobalObject>::cast(type()->AsConstant()->Value())
? Handle<JSGlobalObject>::cast(isolate()->global_object())
: Handle<JSGlobalObject>::cast(holder());
GenerateCheckPropertyCell(masm(), global, name, scratch1, miss);
} else {
......@@ -236,8 +231,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
int accessor_index) {
DCHECK(call_optimization.is_simple_api_call());
Register holder = Frontend(name);
Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
GenerateApiAccessorCall(masm(), call_optimization, receiver_map, receiver(),
GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(),
scratch2(), false, no_reg, holder, accessor_index);
return GetCode(kind(), Code::FAST, name);
}
......@@ -296,8 +290,8 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
Handle<ExecutableAccessorInfo> info =
Handle<ExecutableAccessorInfo>::cast(accessors);
inline_followup = info->getter() != NULL &&
ExecutableAccessorInfo::IsCompatibleReceiverType(
isolate(), info, type());
ExecutableAccessorInfo::IsCompatibleReceiverMap(
isolate(), info, map());
} else if (accessors->IsAccessorPair()) {
Handle<JSObject> property_holder(it->GetHolder<JSObject>());
Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
......@@ -306,9 +300,9 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
if (!property_holder->HasFastProperties()) break;
auto function = Handle<JSFunction>::cast(getter);
CallOptimization call_optimization(function);
Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
Handle<Map> receiver_map = map();
inline_followup = call_optimization.is_simple_api_call() &&
call_optimization.IsCompatibleReceiverType(
call_optimization.IsCompatibleReceiverMap(
receiver_map, property_holder);
}
}
......@@ -335,7 +329,8 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
LookupIterator* it, Register interceptor_reg) {
Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>());
set_type_for_object(holder());
Handle<Map> holder_map(holder()->map());
set_map(holder_map);
set_holder(real_named_property_holder);
Label miss;
......@@ -369,8 +364,7 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
auto function = handle(JSFunction::cast(
AccessorPair::cast(*it->GetAccessors())->getter()));
CallOptimization call_optimization(function);
Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
GenerateApiAccessorCall(masm(), call_optimization, receiver_map,
GenerateApiAccessorCall(masm(), call_optimization, holder_map,
receiver(), scratch2(), false, no_reg, reg,
it->GetAccessorIndex());
}
......@@ -381,7 +375,7 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
Handle<Name> name, int accessor_index, int expected_arguments) {
Register holder = Frontend(name);
GenerateLoadViaGetter(masm(), type(), receiver(), holder, accessor_index,
GenerateLoadViaGetter(masm(), map(), receiver(), holder, accessor_index,
expected_arguments, scratch2());
return GetCode(kind(), Code::FAST, name);
}
......@@ -471,7 +465,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
Handle<JSObject> object, Handle<Name> name, int accessor_index,
int expected_arguments) {
Register holder = Frontend(name);
GenerateStoreViaSetter(masm(), type(), receiver(), holder, accessor_index,
GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index,
expected_arguments, scratch2());
return GetCode(kind(), Code::FAST, name);
......
......@@ -21,11 +21,10 @@ class PropertyHandlerCompiler : public PropertyAccessCompiler {
CacheHolderFlag cache_holder, Code::StubType type);
protected:
PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind,
Handle<HeapType> type, Handle<JSObject> holder,
CacheHolderFlag cache_holder)
PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind, Handle<Map> map,
Handle<JSObject> holder, CacheHolderFlag cache_holder)
: PropertyAccessCompiler(isolate, kind, cache_holder),
type_(type),
map_(map),
holder_(holder) {}
virtual ~PropertyHandlerCompiler() {}
......@@ -99,23 +98,23 @@ class PropertyHandlerCompiler : public PropertyAccessCompiler {
PrototypeCheckType check = CHECK_ALL_MAPS);
Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name);
void set_type_for_object(Handle<Object> object);
void set_holder(Handle<JSObject> holder) { holder_ = holder; }
Handle<HeapType> type() const { return type_; }
Handle<Map> map() const { return map_; }
void set_map(Handle<Map> map) { map_ = map; }
Handle<JSObject> holder() const { return holder_; }
private:
Handle<HeapType> type_;
Handle<Map> map_;
Handle<JSObject> holder_;
};
class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
public:
NamedLoadHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
NamedLoadHandlerCompiler(Isolate* isolate, Handle<Map> map,
Handle<JSObject> holder,
CacheHolderFlag cache_holder)
: PropertyHandlerCompiler(isolate, Code::LOAD_IC, type, holder,
: PropertyHandlerCompiler(isolate, Code::LOAD_IC, map, holder,
cache_holder) {}
virtual ~NamedLoadHandlerCompiler() {}
......@@ -144,16 +143,16 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
// Static interface
static Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
Handle<HeapType> type);
Handle<Map> map);
static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<HeapType> type,
static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<Map> map,
Register receiver, Register holder,
int accessor_index, int expected_arguments,
Register scratch);
static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) {
GenerateLoadViaGetter(masm, Handle<HeapType>::null(), no_reg, no_reg, -1,
-1, no_reg);
GenerateLoadViaGetter(masm, Handle<Map>::null(), no_reg, no_reg, -1, -1,
no_reg);
}
static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
......@@ -213,9 +212,9 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
public:
explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle<Map> map,
Handle<JSObject> holder)
: PropertyHandlerCompiler(isolate, Code::STORE_IC, type, holder,
: PropertyHandlerCompiler(isolate, Code::STORE_IC, map, holder,
kCacheOnReceiver) {}
virtual ~NamedStoreHandlerCompiler() {}
......@@ -233,14 +232,14 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
int expected_arguments);
Handle<Code> CompileStoreInterceptor(Handle<Name> name);
static void GenerateStoreViaSetter(MacroAssembler* masm,
Handle<HeapType> type, Register receiver,
Register holder, int accessor_index,
int expected_arguments, Register scratch);
static void GenerateStoreViaSetter(MacroAssembler* masm, Handle<Map> map,
Register receiver, Register holder,
int accessor_index, int expected_arguments,
Register scratch);
static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) {
GenerateStoreViaSetter(masm, Handle<HeapType>::null(), no_reg, no_reg, -1,
-1, no_reg);
GenerateStoreViaSetter(masm, Handle<Map>::null(), no_reg, no_reg, -1, -1,
no_reg);
}
static void GenerateSlow(MacroAssembler* masm);
......@@ -284,8 +283,8 @@ class ElementHandlerCompiler : public PropertyHandlerCompiler {
public:
explicit ElementHandlerCompiler(Isolate* isolate)
: PropertyHandlerCompiler(isolate, Code::KEYED_LOAD_IC,
Handle<HeapType>::null(),
Handle<JSObject>::null(), kCacheOnReceiver) {}
Handle<Map>::null(), Handle<JSObject>::null(),
kCacheOnReceiver) {}
virtual ~ElementHandlerCompiler() {}
......
......@@ -17,9 +17,8 @@ namespace internal {
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<HeapType> type, Register receiver,
Register holder, int accessor_index, int expected_arguments,
Register scratch) {
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
{
FrameScope scope(masm, StackFrame::INTERNAL);
......@@ -27,7 +26,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
DCHECK(!holder.is(scratch));
DCHECK(!receiver.is(scratch));
// Call the JavaScript getter with the receiver on the stack.
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
if (map->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
__ mov(scratch,
FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
......@@ -237,9 +236,8 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell(
void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
MacroAssembler* masm, Handle<HeapType> type, Register receiver,
Register holder, int accessor_index, int expected_arguments,
Register scratch) {
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
// ----------- S t a t e -------------
// -- esp[0] : return address
// -----------------------------------
......@@ -254,7 +252,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
DCHECK(!receiver.is(scratch));
DCHECK(!value().is(scratch));
// Call the JavaScript setter with receiver and value on the stack.
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
if (map->IsJSGlobalObjectMap()) {
__ mov(scratch,
FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
receiver = scratch;
......@@ -418,7 +416,7 @@ Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss,
PrototypeCheckType check) {
Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
Handle<Map> receiver_map = map();
// Make sure there's no overlap between holder and object registers.
DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
......@@ -430,8 +428,9 @@ Register PropertyHandlerCompiler::CheckPrototypes(
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
if (type()->IsConstant())
current = Handle<JSObject>::cast(type()->AsConstant()->Value());
if (receiver_map->IsJSGlobalObjectMap()) {
current = isolate()->global_object();
}
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
Handle<Map> holder_map(holder()->map());
......
......@@ -36,7 +36,7 @@ void PropertyICCompiler::GenerateRuntimeSetProperty(
#undef __
#define __ ACCESS_MASM(masm())
Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
Handle<Code> PropertyICCompiler::CompilePolymorphic(MapHandleList* maps,
CodeHandleList* handlers,
Handle<Name> name,
Code::StubType type,
......@@ -63,7 +63,7 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
}
Label number_case;
Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
Label* smi_target = IncludesNumberMap(maps) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
// Polymorphic keyed stores may use the map register
......@@ -71,16 +71,15 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
DCHECK(kind() != Code::KEYED_STORE_IC ||
map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister()));
__ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
int receiver_count = types->length();
int receiver_count = maps->length();
int number_of_handled_maps = 0;
for (int current = 0; current < receiver_count; ++current) {
Handle<HeapType> type = types->at(current);
Handle<Map> map = IC::TypeToMap(*type, isolate());
Handle<Map> map = maps->at(current);
if (!map->is_deprecated()) {
number_of_handled_maps++;
Handle<WeakCell> cell = Map::WeakCellForMap(map);
__ CmpWeakValue(map_reg, cell, scratch2());
if (type->Is(HeapType::Number())) {
if (map->instance_type() == HEAP_NUMBER_TYPE) {
DCHECK(!number_case.is_unused());
__ bind(&number_case);
}
......
......@@ -25,30 +25,30 @@ Handle<Code> PropertyICCompiler::Find(Handle<Name> name,
}
bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) {
for (int i = 0; i < types->length(); ++i) {
if (types->at(i)->Is(HeapType::Number())) return true;
bool PropertyICCompiler::IncludesNumberMap(MapHandleList* maps) {
for (int i = 0; i < maps->length(); ++i) {
if (maps->at(i)->instance_type() == HEAP_NUMBER_TYPE) return true;
}
return false;
}
Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type,
Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<Map> map,
Handle<Code> handler,
Handle<Name> name,
IcCheckType check) {
TypeHandleList types(1);
MapHandleList maps(1);
CodeHandleList handlers(1);
types.Add(type);
maps.Add(map);
handlers.Add(handler);
Code::StubType stub_type = handler->type();
return CompilePolymorphic(&types, &handlers, name, stub_type, check);
return CompilePolymorphic(&maps, &handlers, name, stub_type, check);
}
Handle<Code> PropertyICCompiler::ComputeMonomorphic(
Code::Kind kind, Handle<Name> name, Handle<HeapType> type,
Handle<Code> handler, ExtraICState extra_ic_state) {
Code::Kind kind, Handle<Name> name, Handle<Map> map, Handle<Code> handler,
ExtraICState extra_ic_state) {
Isolate* isolate = name->GetIsolate();
if (handler.is_identical_to(isolate->builtins()->LoadIC_Normal()) ||
handler.is_identical_to(isolate->builtins()->StoreIC_Normal())) {
......@@ -56,7 +56,7 @@ Handle<Code> PropertyICCompiler::ComputeMonomorphic(
}
CacheHolderFlag flag;
Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag);
Handle<Map> stub_holder = IC::GetICCacheHolder(map, isolate, &flag);
if (kind == Code::KEYED_STORE_IC) {
// Always set the "property" bit.
extra_ic_state =
......@@ -72,14 +72,14 @@ Handle<Code> PropertyICCompiler::ComputeMonomorphic(
// There are multiple string maps that all use the same prototype. That
// prototype cannot hold multiple handlers, one for each of the string maps,
// for a single name. Hence, turn off caching of the IC.
bool can_be_cached = !type->Is(HeapType::String());
bool can_be_cached = map->instance_type() >= FIRST_NONSTRING_TYPE;
if (can_be_cached) {
ic = Find(name, stub_holder, kind, extra_ic_state, flag);
if (!ic.is_null()) return ic;
}
PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag);
ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY);
ic = ic_compiler.CompileMonomorphic(map, handler, name, PROPERTY);
if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
return ic;
......@@ -98,9 +98,8 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic(
Handle<Code> stub = ComputeKeyedLoadMonomorphicHandler(receiver_map);
PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC);
Handle<Code> code =
compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub,
isolate->factory()->empty_string(), ELEMENT);
Handle<Code> code = compiler.CompileMonomorphic(
receiver_map, stub, isolate->factory()->empty_string(), ELEMENT);
Map::UpdateCodeCache(receiver_map, name, code);
return code;
......@@ -256,7 +255,6 @@ Handle<Code> PropertyICCompiler::ComputeCompareNil(Handle<Map> receiver_map,
}
// TODO(verwaest): Change this method so it takes in a TypeHandleList.
Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
MapHandleList* receiver_maps) {
Isolate* isolate = receiver_maps->at(0)->GetIsolate();
......@@ -267,17 +265,13 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
Handle<Object> probe = cache->Lookup(receiver_maps, flags);
if (probe->IsCode()) return Handle<Code>::cast(probe);
TypeHandleList types(receiver_maps->length());
for (int i = 0; i < receiver_maps->length(); i++) {
types.Add(HeapType::Class(receiver_maps->at(i), isolate));
}
CodeHandleList handlers(receiver_maps->length());
ElementHandlerCompiler compiler(isolate);
compiler.CompileElementHandlers(receiver_maps, &handlers);
PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC);
Handle<Code> code = ic_compiler.CompilePolymorphic(
&types, &handlers, isolate->factory()->empty_string(), Code::NORMAL,
ELEMENT);
receiver_maps, &handlers, isolate->factory()->empty_string(),
Code::NORMAL, ELEMENT);
isolate->counters()->keyed_load_polymorphic_stubs()->Increment();
......@@ -287,13 +281,13 @@ Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
Handle<Code> PropertyICCompiler::ComputePolymorphic(
Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers,
int valid_types, Handle<Name> name, ExtraICState extra_ic_state) {
Code::Kind kind, MapHandleList* maps, CodeHandleList* handlers,
int valid_maps, Handle<Name> name, ExtraICState extra_ic_state) {
Handle<Code> handler = handlers->at(0);
Code::StubType type = valid_types == 1 ? handler->type() : Code::NORMAL;
Code::StubType type = valid_maps == 1 ? handler->type() : Code::NORMAL;
DCHECK(kind == Code::LOAD_IC || kind == Code::STORE_IC);
PropertyICCompiler ic_compiler(name->GetIsolate(), kind, extra_ic_state);
return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY);
return ic_compiler.CompilePolymorphic(maps, handlers, name, type, PROPERTY);
}
......
......@@ -24,10 +24,9 @@ class PropertyICCompiler : public PropertyAccessCompiler {
ExtraICState extra_state);
static Handle<Code> ComputeMonomorphic(Code::Kind kind, Handle<Name> name,
Handle<HeapType> type,
Handle<Code> handler,
Handle<Map> map, Handle<Code> handler,
ExtraICState extra_ic_state);
static Handle<Code> ComputePolymorphic(Code::Kind kind, TypeHandleList* types,
static Handle<Code> ComputePolymorphic(Code::Kind kind, MapHandleList* maps,
CodeHandleList* handlers,
int number_of_valid_maps,
Handle<Name> name,
......@@ -76,11 +75,11 @@ class PropertyICCompiler : public PropertyAccessCompiler {
Handle<Code> CompileStoreGeneric(Code::Flags flags);
Handle<Code> CompileStoreMegamorphic(Code::Flags flags);
Handle<Code> CompileMonomorphic(Handle<HeapType> type, Handle<Code> handler,
Handle<Code> CompileMonomorphic(Handle<Map> map, Handle<Code> handler,
Handle<Name> name, IcCheckType check);
Handle<Code> CompilePolymorphic(TypeHandleList* types,
CodeHandleList* handlers, Handle<Name> name,
Code::StubType type, IcCheckType check);
Handle<Code> CompilePolymorphic(MapHandleList* maps, CodeHandleList* handlers,
Handle<Name> name, Code::StubType type,
IcCheckType check);
Handle<Code> CompileKeyedStoreMonomorphic(Handle<Map> receiver_map,
KeyedAccessStoreMode store_mode);
......@@ -90,7 +89,7 @@ class PropertyICCompiler : public PropertyAccessCompiler {
CodeHandleList* handler_stubs,
MapHandleList* transitioned_maps);
bool IncludesNumberType(TypeHandleList* types);
bool IncludesNumberMap(MapHandleList* maps);
Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name,
InlineCacheState state = MONOMORPHIC);
......
......@@ -161,15 +161,15 @@ Code* IC::raw_target() const {
void IC::UpdateTarget() { target_ = handle(raw_target(), isolate_); }
template <class TypeClass>
JSFunction* IC::GetRootConstructor(TypeClass* type, Context* native_context) {
if (type->Is(TypeClass::Boolean())) {
JSFunction* IC::GetRootConstructor(Map* receiver_map, Context* native_context) {
Isolate* isolate = receiver_map->GetIsolate();
if (receiver_map == isolate->heap()->boolean_map()) {
return native_context->boolean_function();
} else if (type->Is(TypeClass::Number())) {
} else if (receiver_map->instance_type() == HEAP_NUMBER_TYPE) {
return native_context->number_function();
} else if (type->Is(TypeClass::String())) {
} else if (receiver_map->instance_type() < FIRST_NONSTRING_TYPE) {
return native_context->string_function();
} else if (type->Is(TypeClass::Symbol())) {
} else if (receiver_map->instance_type() == SYMBOL_TYPE) {
return native_context->symbol_function();
} else {
return NULL;
......@@ -177,15 +177,15 @@ JSFunction* IC::GetRootConstructor(TypeClass* type, Context* native_context) {
}
Handle<Map> IC::GetHandlerCacheHolder(HeapType* type, bool receiver_is_holder,
Isolate* isolate, CacheHolderFlag* flag) {
Handle<Map> receiver_map = TypeToMap(type, isolate);
Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map,
bool receiver_is_holder, Isolate* isolate,
CacheHolderFlag* flag) {
if (receiver_is_holder) {
*flag = kCacheOnReceiver;
return receiver_map;
}
Context* native_context = *isolate->native_context();
JSFunction* builtin_ctor = GetRootConstructor(type, native_context);
JSFunction* builtin_ctor = GetRootConstructor(*receiver_map, native_context);
if (builtin_ctor != NULL) {
*flag = kCacheOnPrototypeReceiverIsPrimitive;
return handle(HeapObject::cast(builtin_ctor->instance_prototype())->map());
......@@ -198,16 +198,16 @@ Handle<Map> IC::GetHandlerCacheHolder(HeapType* type, bool receiver_is_holder,
}
Handle<Map> IC::GetICCacheHolder(HeapType* type, Isolate* isolate,
Handle<Map> IC::GetICCacheHolder(Handle<Map> map, Isolate* isolate,
CacheHolderFlag* flag) {
Context* native_context = *isolate->native_context();
JSFunction* builtin_ctor = GetRootConstructor(type, native_context);
JSFunction* builtin_ctor = GetRootConstructor(*map, native_context);
if (builtin_ctor != NULL) {
*flag = kCacheOnPrototype;
return handle(builtin_ctor->initial_map());
}
*flag = kCacheOnReceiver;
return TypeToMap(type, isolate);
return map;
}
......
This diff is collapsed.
......@@ -92,14 +92,14 @@ class IC {
bool IsCallStub() const { return target()->is_call_stub(); }
#endif
template <class TypeClass>
static JSFunction* GetRootConstructor(TypeClass* type,
Context* native_context);
static inline Handle<Map> GetHandlerCacheHolder(HeapType* type,
static inline JSFunction* GetRootConstructor(Map* receiver_map,
Context* native_context);
static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map,
bool receiver_is_holder,
Isolate* isolate,
CacheHolderFlag* flag);
static inline Handle<Map> GetICCacheHolder(HeapType* type, Isolate* isolate,
static inline Handle<Map> GetICCacheHolder(Handle<Map> receiver_map,
Isolate* isolate,
CacheHolderFlag* flag);
static bool IsCleared(Code* code) {
......@@ -112,19 +112,6 @@ class IC {
return state == UNINITIALIZED || state == PREMONOMORPHIC;
}
// Utility functions to convert maps to types and back. There are two special
// cases:
// - The heap_number_map is used as a marker which includes heap numbers as
// well as smis.
// - The oddball map is only used for booleans.
static Handle<Map> TypeToMap(HeapType* type, Isolate* isolate);
template <class T>
static typename T::TypeHandle MapToType(Handle<Map> map,
typename T::Region* region);
static Handle<HeapType> CurrentTypeOf(Handle<Object> object,
Isolate* isolate);
static bool ICUseVector(Code::Kind kind) {
return (FLAG_vector_ics &&
(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC)) ||
......@@ -163,10 +150,10 @@ class IC {
// Configure for most states.
void ConfigureVectorState(IC::State new_state);
// Configure the vector for MONOMORPHIC.
void ConfigureVectorState(Handle<Name> name, Handle<HeapType> type,
void ConfigureVectorState(Handle<Name> name, Handle<Map> map,
Handle<Code> handler);
// Configure the vector for POLYMORPHIC.
void ConfigureVectorState(Handle<Name> name, TypeHandleList* types,
void ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
CodeHandleList* handlers);
char TransitionMarkFromState(IC::State state);
......@@ -204,7 +191,7 @@ class IC {
void UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name);
bool UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code);
void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code);
void UpdateMegamorphicCache(Map* map, Name* name, Code* code);
void CopyICToMegamorphicCache(Handle<Name> name);
bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map);
......@@ -227,9 +214,13 @@ class IC {
ExtraICState extra_ic_state() const { return extra_ic_state_; }
void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; }
Handle<HeapType> receiver_type() { return receiver_type_; }
void update_receiver_type(Handle<Object> receiver) {
receiver_type_ = CurrentTypeOf(receiver, isolate_);
Handle<Map> receiver_map() { return receiver_map_; }
void update_receiver_map(Handle<Object> receiver) {
if (receiver->IsSmi()) {
receiver_map_ = isolate_->factory()->heap_number_map();
} else {
receiver_map_ = handle(HeapObject::cast(*receiver)->map());
}
}
void TargetMaps(MapHandleList* list) {
......@@ -239,13 +230,6 @@ class IC {
}
}
void TargetTypes(TypeHandleList* list) {
FindTargetMaps();
for (int i = 0; i < target_maps_.length(); i++) {
list->Add(MapToType<HeapType>(target_maps_.at(i), isolate_));
}
}
Map* FirstTargetMap() {
FindTargetMaps();
return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
......@@ -309,7 +293,7 @@ class IC {
State old_state_; // For saving if we marked as prototype failure.
State state_;
Code::Kind kind_;
Handle<HeapType> receiver_type_;
Handle<Map> receiver_map_;
MaybeHandle<Code> maybe_handler_;
ExtraICState extra_ic_state_;
......
......@@ -215,9 +215,8 @@ void PropertyHandlerCompiler::GenerateCheckPropertyCell(
void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
MacroAssembler* masm, Handle<HeapType> type, Register receiver,
Register holder, int accessor_index, int expected_arguments,
Register scratch) {
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
// ----------- S t a t e -------------
// -- rsp[0] : return address
// -----------------------------------
......@@ -232,7 +231,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
DCHECK(!receiver.is(scratch));
DCHECK(!value().is(scratch));
// Call the JavaScript setter with receiver and value on the stack.
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
if (map->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
__ movp(scratch,
FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
......@@ -262,9 +261,8 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
MacroAssembler* masm, Handle<HeapType> type, Register receiver,
Register holder, int accessor_index, int expected_arguments,
Register scratch) {
MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder,
int accessor_index, int expected_arguments, Register scratch) {
// ----------- S t a t e -------------
// -- rax : receiver
// -- rcx : name
......@@ -277,7 +275,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
DCHECK(!holder.is(scratch));
DCHECK(!receiver.is(scratch));
// Call the JavaScript getter with the receiver on the stack.
if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
if (map->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
__ movp(scratch,
FieldOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
......@@ -416,7 +414,7 @@ Register PropertyHandlerCompiler::CheckPrototypes(
Register object_reg, Register holder_reg, Register scratch1,
Register scratch2, Handle<Name> name, Label* miss,
PrototypeCheckType check) {
Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
Handle<Map> receiver_map = map();
// Make sure there's no overlap between holder and object registers.
DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
......@@ -430,8 +428,8 @@ Register PropertyHandlerCompiler::CheckPrototypes(
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
if (type()->IsConstant()) {
current = Handle<JSObject>::cast(type()->AsConstant()->Value());
if (receiver_map->IsJSGlobalObjectMap()) {
current = isolate()->global_object();
}
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
......
......@@ -72,7 +72,7 @@ Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
}
Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
Handle<Code> PropertyICCompiler::CompilePolymorphic(MapHandleList* maps,
CodeHandleList* handlers,
Handle<Name> name,
Code::StubType type,
......@@ -99,7 +99,7 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
}
Label number_case;
Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
Label* smi_target = IncludesNumberMap(maps) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
// Polymorphic keyed stores may use the map register
......@@ -107,17 +107,16 @@ Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
DCHECK(kind() != Code::KEYED_STORE_IC ||
map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister()));
__ movp(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
int receiver_count = types->length();
int receiver_count = maps->length();
int number_of_handled_maps = 0;
for (int current = 0; current < receiver_count; ++current) {
Handle<HeapType> type = types->at(current);
Handle<Map> map = IC::TypeToMap(*type, isolate());
Handle<Map> map = maps->at(current);
if (!map->is_deprecated()) {
number_of_handled_maps++;
Handle<WeakCell> cell = Map::WeakCellForMap(map);
// Check map and tail call if there's a match
__ CmpWeakValue(map_reg, cell, scratch2());
if (type->Is(HeapType::Number())) {
if (map->instance_type() == HEAP_NUMBER_TYPE) {
DCHECK(!number_case.is_unused());
__ bind(&number_case);
}
......
......@@ -331,11 +331,10 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver,
}
bool AccessorInfo::IsCompatibleReceiverType(Isolate* isolate,
Handle<AccessorInfo> info,
Handle<HeapType> type) {
bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate,
Handle<AccessorInfo> info,
Handle<Map> map) {
if (!info->HasExpectedReceiverType()) return true;
Handle<Map> map = IC::TypeToMap(*type, isolate);
if (!map->IsJSObjectMap()) return false;
return FunctionTemplateInfo::cast(info->expected_receiver_type())
->IsTemplateFor(*map);
......
......@@ -10402,9 +10402,9 @@ class AccessorInfo: public Struct {
inline void set_property_attributes(PropertyAttributes attributes);
// Checks whether the given receiver is compatible with this accessor.
static bool IsCompatibleReceiverType(Isolate* isolate,
Handle<AccessorInfo> info,
Handle<HeapType> type);
static bool IsCompatibleReceiverMap(Isolate* isolate,
Handle<AccessorInfo> info,
Handle<Map> map);
inline bool IsCompatibleReceiver(Object* receiver);
DECLARE_CAST(AccessorInfo)
......
......@@ -207,14 +207,13 @@ Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
}
void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types,
void FeedbackNexus::InstallHandlers(int start_index, MapHandleList* maps,
CodeHandleList* handlers) {
Isolate* isolate = GetIsolate();
Handle<FixedArray> array = handle(FixedArray::cast(GetFeedback()), isolate);
int receiver_count = types->length();
int receiver_count = maps->length();
for (int current = 0; current < receiver_count; ++current) {
Handle<HeapType> type = types->at(current);
Handle<Map> map = IC::TypeToMap(*type, isolate);
Handle<Map> map = maps->at(current);
Handle<WeakCell> cell = Map::WeakCellForMap(map);
array->set(start_index + (current * 2), *cell);
array->set(start_index + (current * 2 + 1), *handlers->at(current));
......@@ -333,10 +332,9 @@ void KeyedLoadICNexus::ConfigurePremonomorphic() {
}
void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type,
void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map,
Handle<Code> handler) {
Handle<FixedArray> array = EnsureArrayOfSize(2);
Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
array->set(0, *cell);
array->set(1, *handler);
......@@ -344,10 +342,9 @@ void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type,
void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<HeapType> type,
Handle<Map> receiver_map,
Handle<Code> handler) {
Handle<FixedArray> array = EnsureArrayOfSize(3);
Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
if (name.is_null()) {
array->set(0, Smi::FromInt(0));
} else {
......@@ -359,25 +356,25 @@ void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
}
void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types,
void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps,
CodeHandleList* handlers) {
int receiver_count = types->length();
int receiver_count = maps->length();
EnsureArrayOfSize(receiver_count * 2);
InstallHandlers(0, types, handlers);
InstallHandlers(0, maps, handlers);
}
void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
TypeHandleList* types,
MapHandleList* maps,
CodeHandleList* handlers) {
int receiver_count = types->length();
int receiver_count = maps->length();
Handle<FixedArray> array = EnsureArrayOfSize(1 + receiver_count * 2);
if (name.is_null()) {
array->set(0, Smi::FromInt(0));
} else {
array->set(0, *name);
}
InstallHandlers(1, types, handlers);
InstallHandlers(1, maps, handlers);
}
......
......@@ -262,7 +262,7 @@ class FeedbackNexus {
}
Handle<FixedArray> EnsureArrayOfSize(int length);
void InstallHandlers(int start_index, TypeHandleList* types,
void InstallHandlers(int start_index, MapHandleList* maps,
CodeHandleList* handlers);
int ExtractMaps(int start_index, MapHandleList* maps) const;
MaybeHandle<Code> FindHandlerForMap(int start_index, Handle<Map> map) const;
......@@ -329,9 +329,9 @@ class LoadICNexus : public FeedbackNexus {
void ConfigureMegamorphic();
void ConfigurePremonomorphic();
void ConfigureMonomorphic(Handle<HeapType> type, Handle<Code> handler);
void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
void ConfigurePolymorphic(TypeHandleList* types, CodeHandleList* handlers);
void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
InlineCacheState StateFromFeedback() const OVERRIDE;
int ExtractMaps(MapHandleList* maps) const OVERRIDE;
......@@ -357,10 +357,10 @@ class KeyedLoadICNexus : public FeedbackNexus {
void ConfigureMegamorphic();
void ConfigurePremonomorphic();
// name can be a null handle for element loads.
void ConfigureMonomorphic(Handle<Name> name, Handle<HeapType> type,
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
Handle<Code> handler);
// name can be null.
void ConfigurePolymorphic(Handle<Name> name, TypeHandleList* types,
void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
CodeHandleList* handlers);
InlineCacheState StateFromFeedback() const OVERRIDE;
......
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