Commit 40d255ec authored by verwaest@chromium.org's avatar verwaest@chromium.org

Move template instance check from Object to FunctionTemplateInfo::IsTemplateFor

BUG=
R=dcarney@chromium.org

Review URL: https://chromiumcodereview.appspot.com/67613005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17876 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9b615194
...@@ -1274,7 +1274,7 @@ int TypeSwitch::match(v8::Handle<Value> value) { ...@@ -1274,7 +1274,7 @@ int TypeSwitch::match(v8::Handle<Value> value) {
i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this); i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
i::FixedArray* types = i::FixedArray::cast(info->types()); i::FixedArray* types = i::FixedArray::cast(info->types());
for (int i = 0; i < types->length(); i++) { for (int i = 0; i < types->length(); i++) {
if (obj->IsInstanceOf(i::FunctionTemplateInfo::cast(types->get(i)))) if (i::FunctionTemplateInfo::cast(types->get(i))->IsTemplateFor(*obj))
return i + 1; return i + 1;
} }
return 0; return 0;
...@@ -3356,7 +3356,7 @@ Local<Object> v8::Object::FindInstanceInPrototypeChain( ...@@ -3356,7 +3356,7 @@ Local<Object> v8::Object::FindInstanceInPrototypeChain(
ENTER_V8(isolate); ENTER_V8(isolate);
i::JSObject* object = *Utils::OpenHandle(this); i::JSObject* object = *Utils::OpenHandle(this);
i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl); i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
while (!object->IsInstanceOf(tmpl_info)) { while (!tmpl_info->IsTemplateFor(object)) {
i::Object* prototype = object->GetPrototype(); i::Object* prototype = object->GetPrototype();
if (!prototype->IsJSObject()) return Local<Object>(); if (!prototype->IsJSObject()) return Local<Object>();
object = i::JSObject::cast(prototype); object = i::JSObject::cast(prototype);
...@@ -5437,7 +5437,7 @@ bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) { ...@@ -5437,7 +5437,7 @@ bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()", ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
return false); return false);
i::Object* obj = *Utils::OpenHandle(*value); i::Object* obj = *Utils::OpenHandle(*value);
return obj->IsInstanceOf(*Utils::OpenHandle(this)); return Utils::OpenHandle(this)->IsTemplateFor(obj);
} }
......
...@@ -2426,8 +2426,8 @@ bool Genesis::ConfigureGlobalObjects( ...@@ -2426,8 +2426,8 @@ bool Genesis::ConfigureGlobalObjects(
bool Genesis::ConfigureApiObject(Handle<JSObject> object, bool Genesis::ConfigureApiObject(Handle<JSObject> object,
Handle<ObjectTemplateInfo> object_template) { Handle<ObjectTemplateInfo> object_template) {
ASSERT(!object_template.is_null()); ASSERT(!object_template.is_null());
ASSERT(object->IsInstanceOf( ASSERT(FunctionTemplateInfo::cast(object_template->constructor())
FunctionTemplateInfo::cast(object_template->constructor()))); ->IsTemplateFor(object->map()));;
bool pending_exception = false; bool pending_exception = false;
Handle<JSObject> obj = Handle<JSObject> obj =
......
...@@ -1104,7 +1104,7 @@ BUILTIN(StrictModePoisonPill) { ...@@ -1104,7 +1104,7 @@ BUILTIN(StrictModePoisonPill) {
static inline Object* FindHidden(Heap* heap, static inline Object* FindHidden(Heap* heap,
Object* object, Object* object,
FunctionTemplateInfo* type) { FunctionTemplateInfo* type) {
if (object->IsInstanceOf(type)) return object; if (type->IsTemplateFor(object)) return object;
Object* proto = object->GetPrototype(heap->isolate()); Object* proto = object->GetPrototype(heap->isolate());
if (proto->IsJSObject() && if (proto->IsJSObject() &&
JSObject::cast(proto)->map()->is_hidden_prototype()) { JSObject::cast(proto)->map()->is_hidden_prototype()) {
......
...@@ -150,25 +150,6 @@ bool Object::IsAccessorInfo() { ...@@ -150,25 +150,6 @@ bool Object::IsAccessorInfo() {
} }
bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
// There is a constraint on the object; check.
if (!this->IsJSObject()) return false;
// Fetch the constructor function of the object.
Object* cons_obj = JSObject::cast(this)->map()->constructor();
if (!cons_obj->IsJSFunction()) return false;
JSFunction* fun = JSFunction::cast(cons_obj);
// Iterate through the chain of inheriting function templates to
// see if the required one occurs.
for (Object* type = fun->shared()->function_data();
type->IsFunctionTemplateInfo();
type = FunctionTemplateInfo::cast(type)->parent_template()) {
if (type == expected) return true;
}
// Didn't find the required type in the inheritance chain.
return false;
}
bool Object::IsSmi() { bool Object::IsSmi() {
return HAS_SMI_TAG(this); return HAS_SMI_TAG(this);
} }
...@@ -5957,7 +5938,7 @@ void AccessorInfo::set_property_attributes(PropertyAttributes attributes) { ...@@ -5957,7 +5938,7 @@ void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
bool AccessorInfo::IsCompatibleReceiver(Object* receiver) { bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
Object* function_template = expected_receiver_type(); Object* function_template = expected_receiver_type();
if (!function_template->IsFunctionTemplateInfo()) return true; if (!function_template->IsFunctionTemplateInfo()) return true;
return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template)); return FunctionTemplateInfo::cast(function_template)->IsTemplateFor(receiver);
} }
......
...@@ -203,6 +203,31 @@ bool Object::ToUint32(uint32_t* value) { ...@@ -203,6 +203,31 @@ bool Object::ToUint32(uint32_t* value) {
} }
bool FunctionTemplateInfo::IsTemplateFor(Object* object) {
if (!object->IsHeapObject()) return false;
return IsTemplateFor(HeapObject::cast(object)->map());
}
bool FunctionTemplateInfo::IsTemplateFor(Map* map) {
// There is a constraint on the object; check.
if (!map->IsJSObjectMap()) return false;
// Fetch the constructor function of the object.
Object* cons_obj = map->constructor();
if (!cons_obj->IsJSFunction()) return false;
JSFunction* fun = JSFunction::cast(cons_obj);
// Iterate through the chain of inheriting function templates to
// see if the required one occurs.
for (Object* type = fun->shared()->function_data();
type->IsFunctionTemplateInfo();
type = FunctionTemplateInfo::cast(type)->parent_template()) {
if (type == this) return true;
}
// Didn't find the required type in the inheritance chain.
return false;
}
template<typename To> template<typename To>
static inline To* CheckedCast(void *from) { static inline To* CheckedCast(void *from) {
uintptr_t temp = reinterpret_cast<uintptr_t>(from); uintptr_t temp = reinterpret_cast<uintptr_t>(from);
......
...@@ -1351,10 +1351,6 @@ class Object : public MaybeObject { ...@@ -1351,10 +1351,6 @@ class Object : public MaybeObject {
inline bool IsExternal(); inline bool IsExternal();
inline bool IsAccessorInfo(); inline bool IsAccessorInfo();
// Returns true if this object is an instance of the specified
// function template.
inline bool IsInstanceOf(FunctionTemplateInfo* type);
inline bool IsStruct(); inline bool IsStruct();
#define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name(); #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) inline bool Is##Name();
STRUCT_LIST(DECLARE_STRUCT_PREDICATE) STRUCT_LIST(DECLARE_STRUCT_PREDICATE)
...@@ -10267,6 +10263,10 @@ class FunctionTemplateInfo: public TemplateInfo { ...@@ -10267,6 +10263,10 @@ class FunctionTemplateInfo: public TemplateInfo {
static const int kLengthOffset = kFlagOffset + kPointerSize; static const int kLengthOffset = kFlagOffset + kPointerSize;
static const int kSize = kLengthOffset + kPointerSize; static const int kSize = kLengthOffset + kPointerSize;
// Returns true if |object| is an instance of this function template.
bool IsTemplateFor(Object* object);
bool IsTemplateFor(Map* map);
private: private:
// Bit position in the flag, from least significant bit position. // Bit position in the flag, from least significant bit position.
static const int kHiddenPrototypeBit = 0; static const int kHiddenPrototypeBit = 0;
......
...@@ -1785,12 +1785,12 @@ int CallOptimization::GetPrototypeDepthOfExpectedType( ...@@ -1785,12 +1785,12 @@ int CallOptimization::GetPrototypeDepthOfExpectedType(
if (expected_receiver_type_.is_null()) return 0; if (expected_receiver_type_.is_null()) return 0;
int depth = 0; int depth = 0;
while (!object.is_identical_to(holder)) { while (!object.is_identical_to(holder)) {
if (object->IsInstanceOf(*expected_receiver_type_)) return depth; if (expected_receiver_type_->IsTemplateFor(object->map())) return depth;
object = Handle<JSObject>(JSObject::cast(object->GetPrototype())); object = Handle<JSObject>(JSObject::cast(object->GetPrototype()));
if (!object->map()->is_hidden_prototype()) return kInvalidProtoDepth; if (!object->map()->is_hidden_prototype()) return kInvalidProtoDepth;
++depth; ++depth;
} }
if (holder->IsInstanceOf(*expected_receiver_type_)) return depth; if (expected_receiver_type_->IsTemplateFor(holder->map())) return depth;
return kInvalidProtoDepth; return kInvalidProtoDepth;
} }
......
...@@ -1037,7 +1037,7 @@ class CallOptimization BASE_EMBEDDED { ...@@ -1037,7 +1037,7 @@ class CallOptimization BASE_EMBEDDED {
bool IsCompatibleReceiver(Object* receiver) { bool IsCompatibleReceiver(Object* receiver) {
ASSERT(is_simple_api_call()); ASSERT(is_simple_api_call());
if (expected_receiver_type_.is_null()) return true; if (expected_receiver_type_.is_null()) return true;
return receiver->IsInstanceOf(*expected_receiver_type_); return expected_receiver_type_->IsTemplateFor(receiver);
} }
private: private:
......
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