Commit 6782d9ce authored by rossberg@chromium.org's avatar rossberg@chromium.org

Implement structural function and array types

Just wanted to add two constructors to a datatype, how ugly can it get?

R=bmeurer@chromium.org, jarin@chromium.org
BUG=

Committed: https://code.google.com/p/v8/source/detail?r=20809

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20815 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3e49c601
......@@ -126,7 +126,7 @@ bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type,
}
if (!type->IsClass()) return false;
Handle<Map> map = type->AsClass();
Handle<Map> map = type->AsClass()->Map();
switch (map->instance_type()) {
case JS_ARRAY_TYPE:
......
......@@ -432,7 +432,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
} else if (representation.IsHeapObject()) {
HeapType* field_type = descriptors->GetFieldType(descriptor);
if (field_type->IsClass()) {
__ CheckMap(value_reg, scratch1, field_type->AsClass(),
__ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
miss_label, DO_SMI_CHECK);
} else {
ASSERT(HeapType::Any()->Is(field_type));
......@@ -601,7 +601,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
} else if (representation.IsHeapObject()) {
HeapType* field_type = lookup->GetFieldType();
if (field_type->IsClass()) {
__ CheckMap(value_reg, scratch1, field_type->AsClass(),
__ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
miss_label, DO_SMI_CHECK);
} else {
ASSERT(HeapType::Any()->Is(field_type));
......@@ -850,7 +850,9 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
if (type->IsConstant()) {
current = Handle<JSObject>::cast(type->AsConstant()->Value());
}
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
Handle<Map> holder_map(holder->map());
......
......@@ -394,7 +394,7 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
} else if (representation.IsHeapObject()) {
HeapType* field_type = descriptors->GetFieldType(descriptor);
if (field_type->IsClass()) {
__ CheckMap(value_reg, scratch1, field_type->AsClass(),
__ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
miss_label, DO_SMI_CHECK);
} else {
ASSERT(HeapType::Any()->Is(field_type));
......@@ -550,7 +550,7 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
} else if (representation.IsHeapObject()) {
HeapType* field_type = lookup->GetFieldType();
if (field_type->IsClass()) {
__ CheckMap(value_reg, scratch1, field_type->AsClass(),
__ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
miss_label, DO_SMI_CHECK);
} else {
ASSERT(HeapType::Any()->Is(field_type));
......@@ -802,7 +802,7 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
Handle<JSObject> current = Handle<JSObject>::null();
if (type->IsConstant()) {
current = Handle<JSObject>::cast(type->AsConstant());
current = Handle<JSObject>::cast(type->AsConstant()->Value());
}
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
......
......@@ -4926,7 +4926,7 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
if (cell->type()->IsConstant()) {
PropertyCell::AddDependentCompilationInfo(cell, top_info());
Handle<Object> constant_object = cell->type()->AsConstant();
Handle<Object> constant_object = cell->type()->AsConstant()->Value();
if (constant_object->IsConsString()) {
constant_object =
String::Flatten(Handle<String>::cast(constant_object));
......@@ -4999,7 +4999,7 @@ void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
static bool CanInlinePropertyAccess(Type* type) {
if (type->Is(Type::NumberOrString())) return true;
if (!type->IsClass()) return false;
Handle<Map> map = type->AsClass();
Handle<Map> map = type->AsClass()->Map();
return map->IsJSObjectMap() &&
!map->is_dictionary_map() &&
!map->has_named_interceptor();
......@@ -5991,7 +5991,7 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
Handle<GlobalObject> global(current_info()->global_object());
Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
if (cell->type()->IsConstant()) {
Handle<Object> constant = cell->type()->AsConstant();
Handle<Object> constant = cell->type()->AsConstant()->Value();
if (value->IsConstant()) {
HConstant* c_value = HConstant::cast(value);
if (!constant.is_identical_to(c_value->handle(isolate()))) {
......@@ -9943,7 +9943,7 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
HValue* operand_to_check =
left->block()->block_id() < right->block()->block_id() ? left : right;
if (combined_type->IsClass()) {
Handle<Map> map = combined_type->AsClass();
Handle<Map> map = combined_type->AsClass()->Map();
AddCheckMap(operand_to_check, map);
HCompareObjectEqAndBranch* result =
New<HCompareObjectEqAndBranch>(left, right);
......
......@@ -2380,7 +2380,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
context = context->native_context();
return handle(context->string_function()->initial_map());
} else {
return type_->AsClass();
return type_->AsClass()->Map();
}
}
Type* type() const { return type_; }
......
......@@ -530,7 +530,8 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
} else if (representation.IsHeapObject()) {
HeapType* field_type = descriptors->GetFieldType(descriptor);
if (field_type->IsClass()) {
__ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK);
__ CheckMap(value_reg, field_type->AsClass()->Map(),
miss_label, DO_SMI_CHECK);
} else {
ASSERT(HeapType::Any()->Is(field_type));
__ JumpIfSmi(value_reg, miss_label);
......@@ -706,7 +707,8 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
} else if (representation.IsHeapObject()) {
HeapType* field_type = lookup->GetFieldType();
if (field_type->IsClass()) {
__ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK);
__ CheckMap(value_reg, field_type->AsClass()->Map(),
miss_label, DO_SMI_CHECK);
} else {
ASSERT(HeapType::Any()->Is(field_type));
__ JumpIfSmi(value_reg, miss_label);
......@@ -836,7 +838,8 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
if (type->IsConstant()) current =
Handle<JSObject>::cast(type->AsConstant()->Value());
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
Handle<Map> holder_map(holder->map());
......
......@@ -680,7 +680,8 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
for (int i = 0; i < number_of_types; i++) {
Handle<HeapType> current_type = types.at(i);
if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) {
if (current_type->IsClass() &&
current_type->AsClass()->Map()->is_deprecated()) {
// Filter out deprecated maps to ensure their instances get migrated.
++deprecated_types;
} else if (type->NowIs(current_type)) {
......@@ -691,8 +692,8 @@ bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
} else if (handler_to_overwrite == -1 &&
current_type->IsClass() &&
type->IsClass() &&
IsTransitionOfMonomorphicTarget(*current_type->AsClass(),
*type->AsClass())) {
IsTransitionOfMonomorphicTarget(*current_type->AsClass()->Map(),
*type->AsClass()->Map())) {
handler_to_overwrite = i;
}
}
......@@ -734,10 +735,11 @@ Handle<Map> IC::TypeToMap(HeapType* type, Isolate* isolate) {
return isolate->factory()->heap_number_map();
if (type->Is(HeapType::Boolean())) return isolate->factory()->boolean_map();
if (type->IsConstant()) {
return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map());
return handle(
Handle<JSGlobalObject>::cast(type->AsConstant()->Value())->map());
}
ASSERT(type->IsClass());
return type->AsClass();
return type->AsClass()->Map();
}
......
......@@ -301,7 +301,7 @@ void JSObject::JSObjectVerify() {
if (r.IsHeapObject()) ASSERT(value->IsHeapObject());
HeapType* field_type = descriptors->GetFieldType(i);
if (field_type->IsClass()) {
Map* map = *field_type->AsClass();
Map* map = *field_type->AsClass()->Map();
CHECK(!map->is_stable() || HeapObject::cast(value)->map() == map);
} else if (r.IsNone()) {
CHECK(field_type->Is(HeapType::None()));
......
......@@ -87,13 +87,6 @@ PropertyDetails PropertyDetails::AsDeleted() const {
}
#define FIXED_TYPED_ARRAY_CAST_ACCESSOR(type) \
template<> \
type* type::cast(Object* object) { \
SLOW_ASSERT(object->Is##type()); \
return reinterpret_cast<type*>(object); \
}
#define INT_ACCESSORS(holder, name, offset) \
int holder::name() { return READ_INT_FIELD(this, offset); } \
void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
......
......@@ -901,7 +901,7 @@ void LoadStubCompiler::NonexistentHandlerFrontend(Handle<HeapType> type,
// check that the global property cell is empty.
if (last_map->IsJSGlobalObjectMap()) {
Handle<JSGlobalObject> global = last.is_null()
? Handle<JSGlobalObject>::cast(type->AsConstant())
? Handle<JSGlobalObject>::cast(type->AsConstant()->Value())
: Handle<JSGlobalObject>::cast(last);
GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
}
......
......@@ -13,6 +13,34 @@
namespace v8 {
namespace internal {
// -------------------------------------------------------------------------- //
// TypeImpl
template<class Config>
typename TypeImpl<Config>::template Iterator<i::Map>
TypeImpl<Config>::Classes() {
if (this->IsBitset()) return Iterator<i::Map>();
return Iterator<i::Map>(Config::handle(this));
}
template<class Config>
typename TypeImpl<Config>::template Iterator<i::Object>
TypeImpl<Config>::Constants() {
if (this->IsBitset()) return Iterator<i::Object>();
return Iterator<i::Object>(Config::handle(this));
}
template<class Config>
TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) {
TypeImpl* t = static_cast<TypeImpl*>(object);
ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() ||
t->IsUnion() || t->IsArray() || t->IsFunction());
return t;
}
template<class Config>
bool TypeImpl<Config>::NowContains(i::Object* value) {
DisallowHeapAllocation no_allocation;
......@@ -27,12 +55,23 @@ bool TypeImpl<Config>::NowContains(i::Object* value) {
}
// -------------------------------------------------------------------------- //
// ZoneTypeConfig
// static
Type* ZoneTypeConfig::handle(Type* type) {
template<class T>
T* ZoneTypeConfig::handle(T* type) {
return type;
}
// static
template<class T>
T* ZoneTypeConfig::cast(Type* type) {
return static_cast<T*>(type);
}
// static
bool ZoneTypeConfig::is_bitset(Type* type) {
return reinterpret_cast<intptr_t>(type) & 1;
......@@ -40,20 +79,20 @@ bool ZoneTypeConfig::is_bitset(Type* type) {
// static
bool ZoneTypeConfig::is_struct(Type* type) {
return !is_bitset(type);
bool ZoneTypeConfig::is_struct(Type* type, int tag) {
return !is_bitset(type) && struct_tag(as_struct(type)) == tag;
}
// static
bool ZoneTypeConfig::is_class(Type* type) {
return is_struct(type) && struct_tag(as_struct(type)) == Type::kClassTag;
return is_struct(type, Type::StructuralType::kClassTag);
}
// static
bool ZoneTypeConfig::is_constant(Type* type) {
return is_struct(type) && struct_tag(as_struct(type)) == Type::kConstantTag;
return is_struct(type, Type::StructuralType::kConstantTag);
}
......@@ -66,7 +105,7 @@ int ZoneTypeConfig::as_bitset(Type* type) {
// static
ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
ASSERT(is_struct(type));
ASSERT(!is_bitset(type));
return reinterpret_cast<Struct*>(type);
}
......@@ -107,7 +146,7 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structured) {
// static
ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
i::Handle<i::Map> map, int lub, Zone* zone) {
Struct* structured = struct_create(Type::kClassTag, 2, zone);
Struct* structured = struct_create(Type::StructuralType::kClassTag, 2, zone);
structured[2] = from_bitset(lub);
structured[3] = map.location();
return from_struct(structured);
......@@ -117,7 +156,8 @@ ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
// static
ZoneTypeConfig::Type* ZoneTypeConfig::from_constant(
i::Handle<i::Object> value, int lub, Zone* zone) {
Struct* structured = struct_create(Type::kConstantTag, 2, zone);
Struct* structured =
struct_create(Type::StructuralType::kConstantTag, 2, zone);
structured[2] = from_bitset(lub);
structured[3] = value.location();
return from_struct(structured);
......@@ -174,14 +214,24 @@ int ZoneTypeConfig::lub_bitset(Type* type) {
return as_bitset(struct_get(as_struct(type), 0));
}
// -------------------------------------------------------------------------- //
// HeapTypeConfig
// static
i::Handle<HeapTypeConfig::Type> HeapTypeConfig::handle(Type* type) {
template<class T>
i::Handle<T> HeapTypeConfig::handle(T* type) {
return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
}
// static
template<class T>
i::Handle<T> HeapTypeConfig::cast(i::Handle<Type> type) {
return i::Handle<T>::cast(type);
}
// static
bool HeapTypeConfig::is_bitset(Type* type) {
return type->IsSmi();
......@@ -201,14 +251,14 @@ bool HeapTypeConfig::is_constant(Type* type) {
// static
bool HeapTypeConfig::is_struct(Type* type) {
return type->IsFixedArray();
bool HeapTypeConfig::is_struct(Type* type, int tag) {
return type->IsFixedArray() && struct_tag(as_struct(type)) == tag;
}
// static
int HeapTypeConfig::as_bitset(Type* type) {
return Smi::cast(type)->value();
return i::Smi::cast(type)->value();
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -496,7 +496,8 @@ void StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
} else if (representation.IsHeapObject()) {
HeapType* field_type = descriptors->GetFieldType(descriptor);
if (field_type->IsClass()) {
__ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK);
__ CheckMap(value_reg, field_type->AsClass()->Map(),
miss_label, DO_SMI_CHECK);
} else {
ASSERT(HeapType::Any()->Is(field_type));
__ JumpIfSmi(value_reg, miss_label);
......@@ -646,7 +647,8 @@ void StoreStubCompiler::GenerateStoreField(MacroAssembler* masm,
} else if (representation.IsHeapObject()) {
HeapType* field_type = lookup->GetFieldType();
if (field_type->IsClass()) {
__ CheckMap(value_reg, field_type->AsClass(), miss_label, DO_SMI_CHECK);
__ CheckMap(value_reg, field_type->AsClass()->Map(),
miss_label, DO_SMI_CHECK);
} else {
ASSERT(HeapType::Any()->Is(field_type));
__ JumpIfSmi(value_reg, miss_label);
......@@ -753,7 +755,9 @@ Register StubCompiler::CheckPrototypes(Handle<HeapType> type,
int depth = 0;
Handle<JSObject> current = Handle<JSObject>::null();
if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant());
if (type->IsConstant()) {
current = Handle<JSObject>::cast(type->AsConstant()->Value());
}
Handle<JSObject> prototype = Handle<JSObject>::null();
Handle<Map> current_map = receiver_map;
Handle<Map> holder_map(holder->map());
......
This diff is collapsed.
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