Revision: 9714
Author: [email protected]
Date: Thu Oct 20 02:35:47 2011
Log: Handlify upper layers of KeyedLoadIC.
BUG=
TEST=
Review URL: http://codereview.chromium.org/8352003
http://code.google.com/p/v8/source/detail?r=9714
Modified:
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/ic.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/stub-cache.h
=======================================
--- /branches/bleeding_edge/src/ic.cc Wed Oct 19 05:10:18 2011
+++ /branches/bleeding_edge/src/ic.cc Thu Oct 20 02:35:47 2011
@@ -366,45 +366,6 @@
static bool HasInterceptorGetter(JSObject* object) {
return !object->GetNamedInterceptor()->getter()->IsUndefined();
}
-
-
-static void LookupForRead(Object* object,
- String* name,
- LookupResult* lookup) {
- AssertNoAllocation no_gc;
- // Skip all the objects with named interceptors, but
- // without actual getter.
- while (true) {
- object->Lookup(name, lookup);
- // Besides normal conditions (property not found or it's not
- // an interceptor), bail out if lookup is not cacheable: we won't
- // be able to IC it anyway and regular lookup should work fine.
- if (!lookup->IsFound()
- || (lookup->type() != INTERCEPTOR)
- || !lookup->IsCacheable()) {
- return;
- }
-
- JSObject* holder = lookup->holder();
- if (HasInterceptorGetter(holder)) {
- return;
- }
-
- holder->LocalLookupRealNamedProperty(name, lookup);
- if (lookup->IsProperty()) {
- ASSERT(lookup->type() != INTERCEPTOR);
- return;
- }
-
- Object* proto = holder->GetPrototype();
- if (proto->IsNull()) {
- lookup->NotFound();
- return;
- }
-
- object = proto;
- }
-}
static void LookupForRead(Handle<Object> object,
@@ -1107,9 +1068,8 @@
bool force_generic_stub) {
// Check for values that can be converted into a symbol.
// TODO(1295): Remove this code.
- HandleScope scope(isolate());
if (key->IsHeapNumber() &&
- isnan(HeapNumber::cast(*key)->value())) {
+ isnan(Handle<HeapNumber>::cast(key)->value())) {
key = isolate()->factory()->nan_symbol();
} else if (key->IsUndefined()) {
key = isolate()->factory()->undefined_symbol();
@@ -1131,13 +1091,11 @@
if (object->IsString() &&
name->Equals(isolate()->heap()->length_symbol())) {
Handle<String> string = Handle<String>::cast(object);
- Object* code = NULL;
- { MaybeObject* maybe_code =
- isolate()->stub_cache()->ComputeKeyedLoadStringLength(*name,
-
*string);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- set_target(Code::cast(code));
+ Handle<Code> code =
+ isolate()->stub_cache()->ComputeKeyedLoadStringLength(name,
+ string);
+ ASSERT(!code.is_null());
+ set_target(*code);
#ifdef DEBUG
TraceIC("KeyedLoadIC", name, state, target());
#endif // DEBUG
@@ -1148,31 +1106,26 @@
if (object->IsJSArray() &&
name->Equals(isolate()->heap()->length_symbol())) {
Handle<JSArray> array = Handle<JSArray>::cast(object);
- Object* code;
- { MaybeObject* maybe_code =
- isolate()->stub_cache()->ComputeKeyedLoadArrayLength(*name,
- *array);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- set_target(Code::cast(code));
+ Handle<Code> code =
+ isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name,
array);
+ ASSERT(!code.is_null());
+ set_target(*code);
#ifdef DEBUG
TraceIC("KeyedLoadIC", name, state, target());
#endif // DEBUG
- return JSArray::cast(*object)->length();
+ return array->length();
}
// Use specialized code for getting prototype of functions.
if (object->IsJSFunction() &&
name->Equals(isolate()->heap()->prototype_symbol()) &&
- JSFunction::cast(*object)->should_have_prototype()) {
+ Handle<JSFunction>::cast(object)->should_have_prototype()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(object);
- Object* code;
- { MaybeObject* maybe_code =
- isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype(
- *name, *function);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- set_target(Code::cast(code));
+ Handle<Code> code =
+ isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype(
+ name, function);
+ ASSERT(!code.is_null());
+ set_target(*code);
#ifdef DEBUG
TraceIC("KeyedLoadIC", name, state, target());
#endif // DEBUG
@@ -1184,15 +1137,14 @@
// the element or char if so.
uint32_t index = 0;
if (name->AsArrayIndex(&index)) {
- HandleScope scope(isolate());
// Rewrite to the generic keyed load stub.
- if (FLAG_use_ic) set_target(generic_stub());
+ if (FLAG_use_ic) set_target(*generic_stub());
return Runtime::GetElementOrCharAt(isolate(), object, index);
}
// Named lookup.
LookupResult lookup(isolate());
- LookupForRead(*object, *name, &lookup);
+ LookupForRead(object, name, &lookup);
// If we did not find a property, check if we need to throw an
exception.
if (!lookup.IsProperty() && IsContextual(object)) {
@@ -1206,17 +1158,15 @@
PropertyAttributes attr;
if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
// Get the property.
- Object* result;
- { MaybeObject* maybe_result =
- object->GetProperty(*object, &lookup, *name, &attr);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
+ 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 *result;
}
return object->GetProperty(*object, &lookup, *name, &attr);
@@ -1227,31 +1177,25 @@
bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
if (use_ic) {
- Code* stub = generic_stub();
+ Handle<Code> stub = generic_stub();
if (!force_generic_stub) {
if (object->IsString() && key->IsNumber()) {
if (state == UNINITIALIZED) {
stub = string_stub();
}
} else if (object->IsJSObject()) {
- JSObject* receiver = JSObject::cast(*object);
- Heap* heap = Handle<JSObject>::cast(object)->GetHeap();
- Map* elements_map =
Handle<JSObject>::cast(object)->elements()->map();
- if (elements_map == heap->non_strict_arguments_elements_map()) {
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ if (receiver->elements()->map() ==
+ isolate()->heap()->non_strict_arguments_elements_map()) {
stub = non_strict_arguments_stub();
} else if (receiver->HasIndexedInterceptor()) {
stub = indexed_interceptor_stub();
- } else if (key->IsSmi() && (target() !=
non_strict_arguments_stub())) {
- MaybeObject* maybe_stub = ComputeStub(receiver,
- LOAD,
- kNonStrictMode,
- stub);
- stub = maybe_stub->IsFailure() ?
- NULL : Code::cast(maybe_stub->ToObjectUnchecked());
+ } else if (key->IsSmi() && (target() !=
*non_strict_arguments_stub())) {
+ stub = ComputeStub(receiver, LOAD, kNonStrictMode, stub);
}
}
}
- if (stub != NULL) set_target(stub);
+ if (!stub.is_null()) set_target(*stub);
}
#ifdef DEBUG
@@ -1263,8 +1207,10 @@
}
-void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state,
- Handle<Object> object, Handle<String> name)
{
+void KeyedLoadIC::UpdateCaches(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;
@@ -1274,63 +1220,57 @@
if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
// Compute the code stub for this load.
- MaybeObject* maybe_code = NULL;
- Object* code;
+ Handle<Code> code;
if (state == UNINITIALIZED) {
// This is the first time we execute this inline cache.
// Set the target to the pre monomorphic stub to delay
// setting the monomorphic state.
- maybe_code = pre_monomorphic_stub();
+ code = pre_monomorphic_stub();
} else {
// Compute a monomorphic stub.
+ Handle<JSObject> holder(lookup->holder());
switch (lookup->type()) {
- case FIELD: {
- maybe_code = isolate()->stub_cache()->ComputeKeyedLoadField(
- *name, *receiver, lookup->holder(), lookup->GetFieldIndex());
+ case FIELD:
+ code = isolate()->stub_cache()->ComputeKeyedLoadField(
+ name, receiver, holder, lookup->GetFieldIndex());
break;
- }
case CONSTANT_FUNCTION: {
- Object* constant = lookup->GetConstantFunction();
- maybe_code = isolate()->stub_cache()->ComputeKeyedLoadConstant(
- *name, *receiver, lookup->holder(), constant);
+ Handle<Object> constant(lookup->GetConstantFunction());
+ code = isolate()->stub_cache()->ComputeKeyedLoadConstant(
+ name, receiver, holder, constant);
break;
}
case CALLBACKS: {
- if (!lookup->GetCallbackObject()->IsAccessorInfo()) return;
- AccessorInfo* callback =
- AccessorInfo::cast(lookup->GetCallbackObject());
+ Handle<Object> callback_object(lookup->GetCallbackObject());
+ if (!callback_object->IsAccessorInfo()) return;
+ Handle<AccessorInfo> callback =
+ Handle<AccessorInfo>::cast(callback_object);
if (v8::ToCData<Address>(callback->getter()) == 0) return;
- maybe_code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
- *name, *receiver, lookup->holder(), callback);
+ code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
+ name, receiver, holder, callback);
break;
}
- case INTERCEPTOR: {
+ case INTERCEPTOR:
ASSERT(HasInterceptorGetter(lookup->holder()));
- maybe_code = isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
- *name, *receiver, lookup->holder());
+ code = isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
+ name, receiver, holder);
break;
- }
- default: {
+ default:
// Always rewrite to the generic case so that we do not
// repeatedly try to rewrite.
- maybe_code = generic_stub();
+ code = generic_stub();
break;
- }
}
}
-
- // If we're unable to compute the stub (not enough memory left), we
- // simply avoid updating the caches.
- if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
// Patch the call site depending on the state of the cache. Make
// sure to always rewrite from monomorphic to megamorphic.
ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
- set_target(Code::cast(code));
+ set_target(*code);
} else if (state == MONOMORPHIC) {
- set_target(megamorphic_stub());
+ set_target(*megamorphic_stub());
}
#ifdef DEBUG
@@ -1566,7 +1506,7 @@
void KeyedIC::GetReceiverMapsForStub(Code* stub, MapList* result) {
ASSERT(stub->is_inline_cache_stub());
- if (stub == string_stub()) {
+ if (!string_stub().is_null() && stub == *string_stub()) {
return result->Add(isolate()->heap()->string_map());
} else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
if (stub->ic_state() == MONOMORPHIC) {
@@ -1584,6 +1524,20 @@
}
}
}
+
+
+Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
+ StubKind stub_kind,
+ StrictModeFlag strict_mode,
+ Handle<Code> generic_stub) {
+ CALL_HEAP_FUNCTION(isolate(),
+ ComputeStub(*receiver,
+ stub_kind,
+ strict_mode,
+ *generic_stub),
+ Code);
+}
+
MaybeObject* KeyedIC::ComputeStub(JSObject* receiver,
@@ -1663,8 +1617,8 @@
Map* receiver_map,
StrictModeFlag strict_mode) {
if ((receiver_map->instance_type() & kNotStringTag) == 0) {
- ASSERT(string_stub() != NULL);
- return string_stub();
+ ASSERT(!string_stub().is_null());
+ return *string_stub();
} else {
ASSERT(receiver_map->has_dictionary_elements() ||
receiver_map->has_fast_elements() ||
@@ -1993,7 +1947,7 @@
// Used from ic-<arch>.cc
RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) {
- NoHandleAllocation na;
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
KeyedLoadIC ic(isolate);
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
@@ -2002,7 +1956,7 @@
RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) {
- NoHandleAllocation na;
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
KeyedLoadIC ic(isolate);
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
=======================================
--- /branches/bleeding_edge/src/ic.h Wed Oct 19 05:10:18 2011
+++ /branches/bleeding_edge/src/ic.h Thu Oct 20 02:35:47 2011
@@ -356,12 +356,17 @@
ElementsKind elements_kind) = 0;
protected:
- virtual Code* string_stub() {
- return NULL;
+ virtual Handle<Code> string_stub() {
+ return Handle<Code>::null();
}
virtual Code::Kind kind() const = 0;
+ Handle<Code> ComputeStub(Handle<JSObject> receiver,
+ StubKind stub_kind,
+ StrictModeFlag strict_mode,
+ Handle<Code> default_stub);
+
MaybeObject* ComputeStub(JSObject* receiver,
StubKind stub_kind,
StrictModeFlag strict_mode,
@@ -433,9 +438,8 @@
MapList* receiver_maps,
StrictModeFlag strict_mode);
- virtual Code* string_stub() {
- return isolate()->builtins()->builtin(
- Builtins::kKeyedLoadIC_String);
+ virtual Handle<Code> string_stub() {
+ return isolate()->builtins()->KeyedLoadIC_String();
}
private:
@@ -450,25 +454,20 @@
return Isolate::Current()->builtins()->builtin(
Builtins::kKeyedLoadIC_Initialize);
}
- Code* megamorphic_stub() {
- return isolate()->builtins()->builtin(
- Builtins::kKeyedLoadIC_Generic);
- }
- Code* generic_stub() {
- return isolate()->builtins()->builtin(
- Builtins::kKeyedLoadIC_Generic);
- }
- Code* pre_monomorphic_stub() {
- return isolate()->builtins()->builtin(
- Builtins::kKeyedLoadIC_PreMonomorphic);
- }
- Code* indexed_interceptor_stub() {
- return isolate()->builtins()->builtin(
- Builtins::kKeyedLoadIC_IndexedInterceptor);
- }
- Code* non_strict_arguments_stub() {
- return isolate()->builtins()->builtin(
- Builtins::kKeyedLoadIC_NonStrictArguments);
+ Handle<Code> megamorphic_stub() {
+ return isolate()->builtins()->KeyedLoadIC_Generic();
+ }
+ Handle<Code> generic_stub() {
+ return isolate()->builtins()->KeyedLoadIC_Generic();
+ }
+ Handle<Code> pre_monomorphic_stub() {
+ return isolate()->builtins()->KeyedLoadIC_PreMonomorphic();
+ }
+ Handle<Code> indexed_interceptor_stub() {
+ return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
+ }
+ Handle<Code> non_strict_arguments_stub() {
+ return isolate()->builtins()->KeyedLoadIC_NonStrictArguments();
}
static void Clear(Address address, Code* target);
=======================================
--- /branches/bleeding_edge/src/objects.cc Wed Oct 19 05:10:18 2011
+++ /branches/bleeding_edge/src/objects.cc Thu Oct 20 02:35:47 2011
@@ -4655,6 +4655,13 @@
return new_map;
}
+void Map::UpdateCodeCache(Handle<Map> map,
+ Handle<String> name,
+ Handle<Code> code) {
+ Isolate* isolate = map->GetIsolate();
+ CALL_HEAP_FUNCTION_VOID(isolate,
+ map->UpdateCodeCache(*name, *code));
+}
MaybeObject* Map::UpdateCodeCache(String* name, Code* code) {
// Allocate the code cache if not present.
=======================================
--- /branches/bleeding_edge/src/objects.h Wed Oct 19 05:15:02 2011
+++ /branches/bleeding_edge/src/objects.h Thu Oct 20 02:35:47 2011
@@ -4258,6 +4258,9 @@
inline void ClearCodeCache(Heap* heap);
// Update code cache.
+ static void UpdateCodeCache(Handle<Map> map,
+ Handle<String> name,
+ Handle<Code> code);
MUST_USE_RESULT MaybeObject* UpdateCodeCache(String* name, Code* code);
// Returns the found code or undefined if absent.
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Wed Oct 19 02:17:01 2011
+++ /branches/bleeding_edge/src/stub-cache.cc Thu Oct 20 02:35:47 2011
@@ -306,187 +306,193 @@
}
-MaybeObject* StubCache::ComputeKeyedLoadField(String* name,
- JSObject* receiver,
- JSObject* holder,
+Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
+ Handle<JSObject>
object,
+ Handle<JSObject>
holder,
+ int index) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileLoadField(*name, *object, *holder, index),
+ Code);
+}
+
+
+Handle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
int field_index) {
- ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
+ ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
FIELD);
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- KeyedLoadStubCompiler compiler(isolate_);
- { MaybeObject* maybe_code =
- compiler.CompileLoadField(name, receiver, holder, field_index);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code),
name));
- GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name,
Code::cast(code)));
- Object* result;
- { MaybeObject* maybe_result =
- receiver->UpdateMapCodeCache(name, Code::cast(code));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- }
+ Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
+ if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+ KeyedLoadStubCompiler compiler(isolate_);
+ Handle<Code> code =
+ compiler.CompileLoadField(name, receiver, holder, field_index);
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code,
*name));
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
-MaybeObject* StubCache::ComputeKeyedLoadConstant(String* name,
- JSObject* receiver,
- JSObject* holder,
- Object* value) {
- ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
+Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(Handle<String>
name,
+ Handle<JSObject>
object,
+ Handle<JSObject>
holder,
+ Handle<Object>
value) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileLoadConstant(*name, *object, *holder, *value),
+ Code);
+}
+
+
+Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<Object> value) {
+ ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
CONSTANT_FUNCTION);
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- KeyedLoadStubCompiler compiler(isolate_);
- { MaybeObject* maybe_code =
- compiler.CompileLoadConstant(name, receiver, holder, value);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code),
name));
- GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name,
Code::cast(code)));
- Object* result;
- { MaybeObject* maybe_result =
- receiver->UpdateMapCodeCache(name, Code::cast(code));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- }
+ Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
+ if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+ KeyedLoadStubCompiler compiler(isolate_);
+ Handle<Code> code =
+ compiler.CompileLoadConstant(name, receiver, holder, value);
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code,
*name));
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
-MaybeObject* StubCache::ComputeKeyedLoadInterceptor(String* name,
- JSObject* receiver,
- JSObject* holder) {
- ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
+Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<String> name) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileLoadInterceptor(*object, *holder, *name),
+ Code);
+}
+
+
+Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
+ Handle<JSObject>
receiver,
+ Handle<JSObject>
holder) {
+ ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR);
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- KeyedLoadStubCompiler compiler(isolate_);
- { MaybeObject* maybe_code =
- compiler.CompileLoadInterceptor(receiver, holder, name);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code),
name));
- GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name,
Code::cast(code)));
- Object* result;
- { MaybeObject* maybe_result =
- receiver->UpdateMapCodeCache(name, Code::cast(code));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- }
+ Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
+ if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+ KeyedLoadStubCompiler compiler(isolate_);
+ Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder,
name);
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code,
*name));
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
-MaybeObject* StubCache::ComputeKeyedLoadCallback(String* name,
- JSObject* receiver,
- JSObject* holder,
- AccessorInfo* callback) {
- ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
+Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
+ Handle<String> name,
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<AccessorInfo> callback) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileLoadCallback(*name, *object, *holder,
*callback),
+ Code);
+}
+
+
+Handle<Code> StubCache::ComputeKeyedLoadCallback(
+ Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<AccessorInfo> callback) {
+ ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- KeyedLoadStubCompiler compiler(isolate_);
- { MaybeObject* maybe_code =
- compiler.CompileLoadCallback(name, receiver, holder, callback);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code),
name));
- GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name,
Code::cast(code)));
- Object* result;
- { MaybeObject* maybe_result =
- receiver->UpdateMapCodeCache(name, Code::cast(code));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- }
+ Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
+ if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+ KeyedLoadStubCompiler compiler(isolate_);
+ Handle<Code> code =
+ compiler.CompileLoadCallback(name, receiver, holder, callback);
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code,
*name));
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
-
-MaybeObject* StubCache::ComputeKeyedLoadArrayLength(String* name,
- JSArray* receiver) {
+Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength(
+ Handle<String> name) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileLoadArrayLength(*name),
+ Code);
+}
+
+Handle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name,
+ Handle<JSArray>
receiver) {
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
- ASSERT(receiver->IsJSObject());
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- KeyedLoadStubCompiler compiler(isolate_);
- { MaybeObject* maybe_code = compiler.CompileLoadArrayLength(name);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code),
name));
- GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name,
Code::cast(code)));
- Object* result;
- { MaybeObject* maybe_result =
- receiver->UpdateMapCodeCache(name, Code::cast(code));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- }
+ Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
+ if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+ KeyedLoadStubCompiler compiler(isolate_);
+ Handle<Code> code = compiler.CompileLoadArrayLength(name);
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code,
*name));
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
-MaybeObject* StubCache::ComputeKeyedLoadStringLength(String* name,
- String* receiver) {
+Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength(
+ Handle<String> name) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileLoadStringLength(*name),
+ Code);
+}
+
+Handle<Code> StubCache::ComputeKeyedLoadStringLength(Handle<String> name,
+ Handle<String>
receiver) {
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
- Map* map = receiver->map();
- Object* code = map->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- KeyedLoadStubCompiler compiler(isolate_);
- { MaybeObject* maybe_code = compiler.CompileLoadStringLength(name);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code),
name));
- GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name,
Code::cast(code)));
- Object* result;
- { MaybeObject* maybe_result = map->UpdateCodeCache(name,
Code::cast(code));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- }
+ Handle<Map> map(receiver->map());
+ Handle<Object> probe(map->FindInCodeCache(*name, flags));
+ if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+ KeyedLoadStubCompiler compiler(isolate_);
+ Handle<Code> code = compiler.CompileLoadStringLength(name);
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code,
*name));
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
+ Map::UpdateCodeCache(map, name, code);
return code;
}
-MaybeObject* StubCache::ComputeKeyedLoadFunctionPrototype(
- String* name,
- JSFunction* receiver) {
+Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype(
+ Handle<String> name) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileLoadFunctionPrototype(*name),
+ Code);
+}
+
+
+Handle<Code> StubCache::ComputeKeyedLoadFunctionPrototype(
+ Handle<String> name,
+ Handle<JSFunction> receiver) {
Code::Flags flags =
Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- KeyedLoadStubCompiler compiler(isolate_);
- { MaybeObject* maybe_code =
compiler.CompileLoadFunctionPrototype(name);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code),
name));
- GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name,
Code::cast(code)));
- Object* result;
- { MaybeObject* maybe_result =
- receiver->UpdateMapCodeCache(name, Code::cast(code));
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- }
+ Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
+ if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+ KeyedLoadStubCompiler compiler(isolate_);
+ Handle<Code> code = compiler.CompileLoadFunctionPrototype(name);
+ PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code,
*name));
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
=======================================
--- /branches/bleeding_edge/src/stub-cache.h Wed Oct 19 02:17:01 2011
+++ /branches/bleeding_edge/src/stub-cache.h Thu Oct 20 02:35:47 2011
@@ -108,39 +108,33 @@
// ---
- MUST_USE_RESULT MaybeObject* ComputeKeyedLoadField(String* name,
- JSObject* receiver,
- JSObject* holder,
- int field_index);
-
- MUST_USE_RESULT MaybeObject* ComputeKeyedLoadCallback(
- String* name,
- JSObject* receiver,
- JSObject* holder,
- AccessorInfo* callback);
-
- MUST_USE_RESULT MaybeObject* ComputeKeyedLoadConstant(
- String* name,
- JSObject* receiver,
- JSObject* holder,
- Object* value);
-
- MUST_USE_RESULT MaybeObject* ComputeKeyedLoadInterceptor(
- String* name,
- JSObject* receiver,
- JSObject* holder);
-
- MUST_USE_RESULT MaybeObject* ComputeKeyedLoadArrayLength(
- String* name,
- JSArray* receiver);
-
- MUST_USE_RESULT MaybeObject* ComputeKeyedLoadStringLength(
- String* name,
- String* receiver);
-
- MUST_USE_RESULT MaybeObject* ComputeKeyedLoadFunctionPrototype(
- String* name,
- JSFunction* receiver);
+ Handle<Code> ComputeKeyedLoadField(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ int field_index);
+
+ Handle<Code> ComputeKeyedLoadCallback(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<AccessorInfo> callback);
+
+ Handle<Code> ComputeKeyedLoadConstant(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder,
+ Handle<Object> value);
+
+ Handle<Code> ComputeKeyedLoadInterceptor(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<JSObject> holder);
+
+ Handle<Code> ComputeKeyedLoadArrayLength(Handle<String> name,
+ Handle<JSArray> receiver);
+
+ Handle<Code> ComputeKeyedLoadStringLength(Handle<String> name,
+ Handle<String> receiver);
+
+ Handle<Code> ComputeKeyedLoadFunctionPrototype(Handle<String> name,
+ Handle<JSFunction>
receiver);
// ---
@@ -638,27 +632,55 @@
class KeyedLoadStubCompiler: public StubCompiler {
public:
explicit KeyedLoadStubCompiler(Isolate* isolate) : StubCompiler(isolate)
{ }
+
+ Handle<Code> CompileLoadField(Handle<String> name,
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ int index);
+
MUST_USE_RESULT MaybeObject* CompileLoadField(String* name,
JSObject* object,
JSObject* holder,
int index);
+ Handle<Code> CompileLoadCallback(Handle<String> name,
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<AccessorInfo> callback);
+
MUST_USE_RESULT MaybeObject* CompileLoadCallback(String* name,
JSObject* object,
JSObject* holder,
AccessorInfo* callback);
+ Handle<Code> CompileLoadConstant(Handle<String> name,
+ Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<Object> value);
+
MUST_USE_RESULT MaybeObject* CompileLoadConstant(String* name,
JSObject* object,
JSObject* holder,
Object* value);
+ Handle<Code> CompileLoadInterceptor(Handle<JSObject> object,
+ Handle<JSObject> holder,
+ Handle<String> name);
+
MUST_USE_RESULT MaybeObject* CompileLoadInterceptor(JSObject* object,
JSObject* holder,
String* name);
+ Handle<Code> CompileLoadArrayLength(Handle<String> name);
+
MUST_USE_RESULT MaybeObject* CompileLoadArrayLength(String* name);
+
+ Handle<Code> CompileLoadStringLength(Handle<String> name);
+
MUST_USE_RESULT MaybeObject* CompileLoadStringLength(String* name);
+
+ Handle<Code> CompileLoadFunctionPrototype(Handle<String> name);
+
MUST_USE_RESULT MaybeObject* CompileLoadFunctionPrototype(String* name);
MUST_USE_RESULT MaybeObject* CompileLoadElement(Map* receiver_map);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev