Optimize typed-array length loading.

R=dslomov@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16845 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2013-09-19 18:19:24 +00:00
parent cd4dba243c
commit f74c62e58b
4 changed files with 37 additions and 6 deletions

View File

@ -5670,6 +5670,13 @@ class HObjectAccess V8_FINAL {
? Representation::Smi() : Representation::Tagged()); ? Representation::Smi() : Representation::Tagged());
} }
static HObjectAccess ForTypedArrayLength() {
return HObjectAccess(
kInobject,
JSTypedArray::kLengthOffset,
Representation::Tagged());
}
static HObjectAccess ForAllocationSiteTransitionInfo() { static HObjectAccess ForAllocationSiteTransitionInfo() {
return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset); return HObjectAccess(kInobject, AllocationSite::kTransitionInfoOffset);
} }

View File

@ -4630,6 +4630,13 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanLoadAsMonomorphic(
return true; return true;
} }
if (IsTypedArrayLength()) {
for (int i = 1; i < types->length(); ++i) {
if (types->at(i)->instance_type() != JS_TYPED_ARRAY_TYPE) return false;
}
return true;
}
for (int i = 1; i < types->length(); ++i) { for (int i = 1; i < types->length(); ++i) {
PropertyAccessInfo test_info(isolate(), types->at(i), name_); PropertyAccessInfo test_info(isolate(), types->at(i), name_);
if (!test_info.IsCompatibleForLoad(this)) return false; if (!test_info.IsCompatibleForLoad(this)) return false;
@ -4657,6 +4664,11 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadMonomorphic(
info->map()->elements_kind())); info->map()->elements_kind()));
} }
if (info->IsTypedArrayLength()) {
return New<HLoadNamedField>(
checked_object, HObjectAccess::ForTypedArrayLength());
}
HValue* checked_holder = checked_object; HValue* checked_holder = checked_object;
if (info->has_holder()) { if (info->has_holder()) {
Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));

View File

@ -1982,6 +1982,11 @@ class HOptimizedGraphBuilder V8_FINAL
name_->Equals(isolate()->heap()->length_string()); name_->Equals(isolate()->heap()->length_string());
} }
bool IsTypedArrayLength() {
return map_->instance_type() == JS_TYPED_ARRAY_TYPE &&
name_->Equals(isolate()->heap()->length_string());
}
bool has_holder() { return !holder_.is_null(); } bool has_holder() { return !holder_.is_null(); }
LookupResult* lookup() { return &lookup_; } LookupResult* lookup() { return &lookup_; }

View File

@ -1349,6 +1349,19 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
return isolate()->stub_cache()->ComputeLoadNormal(name, receiver); return isolate()->stub_cache()->ComputeLoadNormal(name, receiver);
case CALLBACKS: { case CALLBACKS: {
Handle<Object> callback(lookup->GetCallbackObject(), isolate()); Handle<Object> callback(lookup->GetCallbackObject(), isolate());
if (name->Equals(isolate()->heap()->length_string())) {
if (receiver->IsJSArray()) {
PropertyIndex lengthIndex = PropertyIndex::NewHeaderIndex(
JSArray::kLengthOffset / kPointerSize);
return isolate()->stub_cache()->ComputeLoadField(
name, receiver, receiver, lengthIndex, Representation::Tagged());
} else if (receiver->IsJSTypedArray()) {
PropertyIndex lengthIndex = PropertyIndex::NewHeaderIndex(
JSTypedArray::kLengthOffset / kPointerSize);
return isolate()->stub_cache()->ComputeLoadField(
name, receiver, receiver, lengthIndex, Representation::Tagged());
}
}
if (callback->IsExecutableAccessorInfo()) { if (callback->IsExecutableAccessorInfo()) {
Handle<ExecutableAccessorInfo> info = Handle<ExecutableAccessorInfo> info =
Handle<ExecutableAccessorInfo>::cast(callback); Handle<ExecutableAccessorInfo>::cast(callback);
@ -1371,12 +1384,6 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
} }
return isolate()->stub_cache()->ComputeLoadViaGetter( return isolate()->stub_cache()->ComputeLoadViaGetter(
name, receiver, holder, function); name, receiver, holder, function);
} else if (receiver->IsJSArray() &&
name->Equals(isolate()->heap()->length_string())) {
PropertyIndex lengthIndex = PropertyIndex::NewHeaderIndex(
JSArray::kLengthOffset / kPointerSize);
return isolate()->stub_cache()->ComputeLoadField(
name, receiver, holder, lengthIndex, Representation::Tagged());
} }
// TODO(dcarney): Handle correctly. // TODO(dcarney): Handle correctly.
if (callback->IsDeclaredAccessorInfo()) break; if (callback->IsDeclaredAccessorInfo()) break;