Merge Load from Keyed|Named load code.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13460 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2013-01-22 09:35:14 +00:00
parent b79a927e74
commit 3ffcbe3319
2 changed files with 56 additions and 112 deletions

119
src/ic.cc
View File

@ -832,10 +832,15 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
}
bool IC::HandleLoad(State state,
Handle<Object> object,
Handle<String> name,
MaybeObject** result) {
MaybeObject* IC::Load(State state,
Handle<Object> object,
Handle<String> name) {
// If the object is undefined or null it's illegal to try to get any
// of its properties; throw a TypeError in that case.
if (object->IsUndefined() || object->IsNull()) {
return TypeError("non_object_property_load", object, name);
}
if (FLAG_use_ic) {
// Use specialized code for getting the length of strings and
// string wrapper objects. The length property of string wrapper
@ -866,8 +871,7 @@ bool IC::HandleLoad(State state,
Handle<Object> string = object->IsJSValue()
? Handle<Object>(Handle<JSValue>::cast(object)->value())
: object;
*result = Smi::FromInt(String::cast(*string)->length());
return true;
return Smi::FromInt(String::cast(*string)->length());
}
// Use specialized code for getting the length of arrays.
@ -889,8 +893,7 @@ bool IC::HandleLoad(State state,
if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
#endif
}
*result = JSArray::cast(*object)->length();
return true;
return JSArray::cast(*object)->length();
}
// Use specialized code for getting prototype of functions.
@ -913,33 +916,18 @@ bool IC::HandleLoad(State state,
if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
#endif
}
*result = Accessors::FunctionGetPrototype(*object, 0);
return true;
return Accessors::FunctionGetPrototype(*object, 0);
}
}
return false;
}
MaybeObject* LoadIC::Load(State state,
Handle<Object> object,
Handle<String> name) {
// If the object is undefined or null it's illegal to try to get any
// of its properties; throw a TypeError in that case.
if (object->IsUndefined() || object->IsNull()) {
return TypeError("non_object_property_load", object, name);
}
MaybeObject* result;
if (HandleLoad(state, object, name, &result)) {
return result;
}
// Check if the name is trivially convertible to an index and get
// the element if so.
// the element or char if so.
uint32_t index;
if (name->AsArrayIndex(&index)) return object->GetElement(index);
if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
// Rewrite to the generic keyed load stub.
if (FLAG_use_ic) set_target(*generic_stub());
return Runtime::GetElementOrCharAt(isolate(), object, index);
}
// Named lookup in the object.
LookupResult lookup(isolate());
@ -955,7 +943,7 @@ MaybeObject* LoadIC::Load(State state,
// Update inline cache and stub cache.
if (FLAG_use_ic) {
UpdateCaches(&lookup, state, object, name);
UpdateLoadCaches(&lookup, state, object, name);
}
PropertyAttributes attr;
@ -977,10 +965,10 @@ MaybeObject* LoadIC::Load(State state,
}
void LoadIC::UpdateCaches(LookupResult* lookup,
State state,
Handle<Object> object,
Handle<String> name) {
void LoadIC::UpdateLoadCaches(LookupResult* lookup,
State state,
Handle<Object> object,
Handle<String> name) {
// Bail out if the result is not cacheable.
if (!lookup->IsCacheable()) return;
@ -1165,56 +1153,7 @@ MaybeObject* KeyedLoadIC::Load(State state,
key = TryConvertKey(key, isolate());
if (key->IsSymbol()) {
Handle<String> name = Handle<String>::cast(key);
// If the object is undefined or null it's illegal to try to get any
// of its properties; throw a TypeError in that case.
if (object->IsUndefined() || object->IsNull()) {
return TypeError("non_object_property_load", object, name);
}
MaybeObject* result;
if (HandleLoad(state, object, name, &result)) {
return result;
}
// Check if the name is trivially convertible to an index and get
// the element or char if so.
uint32_t index = 0;
if (name->AsArrayIndex(&index)) {
// Rewrite to the generic keyed load stub.
if (FLAG_use_ic) set_target(*generic_stub());
return Runtime::GetElementOrCharAt(isolate(), object, index);
}
// Named lookup.
LookupResult lookup(isolate());
LookupForRead(object, name, &lookup);
// If we did not find a property, check if we need to throw an exception.
if (!lookup.IsFound() && IsContextual(object)) {
return ReferenceError("not_defined", name);
}
if (FLAG_use_ic) {
UpdateCaches(&lookup, state, object, name);
}
PropertyAttributes attr;
if (lookup.IsInterceptor()) {
// Get the property.
Handle<Object> result =
Object::GetProperty(object, object, &lookup, name, &attr);
RETURN_IF_EMPTY_HANDLE(isolate(), result);
// If the property is not present, check if we need to throw an
// exception.
if (attr == ABSENT && IsContextual(object)) {
return ReferenceError("not_defined", name);
}
return *result;
}
return object->GetProperty(*object, &lookup, *name, &attr);
return IC::Load(state, object, Handle<String>::cast(key));
}
// Do not use ICs for objects that require access checks (including
@ -1236,7 +1175,7 @@ MaybeObject* KeyedLoadIC::Load(State state,
} else if (receiver->HasIndexedInterceptor()) {
stub = indexed_interceptor_stub();
} else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
stub = ComputeStub(receiver, LOAD, kNonStrictMode, stub);
stub = ComputeStub(receiver, KeyedIC::LOAD, kNonStrictMode, stub);
}
}
} else {
@ -1252,10 +1191,10 @@ MaybeObject* KeyedLoadIC::Load(State state,
}
void KeyedLoadIC::UpdateCaches(LookupResult* lookup,
State state,
Handle<Object> object,
Handle<String> name) {
void KeyedLoadIC::UpdateLoadCaches(LookupResult* lookup,
State state,
Handle<Object> object,
Handle<String> name) {
// Bail out if we didn't find a result.
if (!lookup->IsProperty() || !lookup->IsCacheable()) return;

View File

@ -132,6 +132,10 @@ class IC {
static inline JSObject* GetCodeCacheHolder(Object* object,
InlineCacheHolderFlag holder);
MUST_USE_RESULT MaybeObject* Load(State state,
Handle<Object> object,
Handle<String> name);
protected:
virtual Handle<Code> pre_monomorphic_stub() {
UNREACHABLE();
@ -141,10 +145,20 @@ class IC {
UNREACHABLE();
return Handle<Code>::null();
}
virtual Handle<Code> generic_stub() const {
UNREACHABLE();
return Handle<Code>::null();
}
virtual Code::Kind kind() const {
UNREACHABLE();
return Code::STUB;
}
virtual void UpdateLoadCaches(LookupResult* lookup,
State state,
Handle<Object> object,
Handle<String> name) {
UNREACHABLE();
}
Address fp() const { return fp_; }
Address pc() const { return *pc_address_; }
Isolate* isolate() const { return isolate_; }
@ -177,11 +191,6 @@ class IC {
static inline void SetTargetAtAddress(Address address, Code* target);
static void PostPatching(Address address, Code* target, Code* old_target);
bool HandleLoad(State state,
Handle<Object> object,
Handle<String> name,
MaybeObject** result);
private:
// Frame pointer for the frame that uses (calls) the IC.
Address fp_;
@ -340,10 +349,6 @@ class LoadIC: public IC {
ASSERT(target()->is_load_stub());
}
MUST_USE_RESULT MaybeObject* Load(State state,
Handle<Object> object,
Handle<String> name);
// Code generator routines.
static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
static void GeneratePreMonomorphic(MacroAssembler* masm) {
@ -364,14 +369,14 @@ class LoadIC: public IC {
return isolate()->builtins()->LoadIC_Megamorphic();
}
private:
// Update the inline cache and the global stub cache based on the
// lookup result.
void UpdateCaches(LookupResult* lookup,
State state,
Handle<Object> object,
Handle<String> name);
virtual void UpdateLoadCaches(LookupResult* lookup,
State state,
Handle<Object> object,
Handle<String> name);
private:
// Stub accessors.
static Code* initialize_stub() {
return Isolate::Current()->builtins()->builtin(
@ -540,6 +545,9 @@ class KeyedLoadIC: public KeyedIC {
virtual Handle<Code> megamorphic_stub() {
return isolate()->builtins()->KeyedLoadIC_Generic();
}
virtual Handle<Code> generic_stub() const {
return isolate()->builtins()->KeyedLoadIC_Generic();
}
virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
StrictModeFlag strict_mode,
@ -549,21 +557,18 @@ class KeyedLoadIC: public KeyedIC {
return isolate()->builtins()->KeyedLoadIC_String();
}
private:
// Update the inline cache.
void UpdateCaches(LookupResult* lookup,
State state,
Handle<Object> object,
Handle<String> name);
virtual void UpdateLoadCaches(LookupResult* lookup,
State state,
Handle<Object> object,
Handle<String> name);
private:
// Stub accessors.
static Code* initialize_stub() {
return Isolate::Current()->builtins()->builtin(
Builtins::kKeyedLoadIC_Initialize);
}
Handle<Code> generic_stub() const {
return isolate()->builtins()->KeyedLoadIC_Generic();
}
virtual Handle<Code> pre_monomorphic_stub() {
return isolate()->builtins()->KeyedLoadIC_PreMonomorphic();
}