}
-static bool LookupForWrite(JSObject* receiver,
- String* name,
+static bool LookupForWrite(Handle<JSObject> receiver,
+ Handle<String> name,
LookupResult* lookup) {
- receiver->LocalLookup(name, lookup);
+ receiver->LocalLookup(*name, lookup);
if (!StoreICableLookup(lookup)) {
return false;
}
if (lookup->type() == INTERCEPTOR &&
receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
- receiver->LocalLookupRealNamedProperty(name, lookup);
+ receiver->LocalLookupRealNamedProperty(*name, lookup);
return StoreICableLookup(lookup);
}
// Check if the given name is an array index.
uint32_t index;
if (name->AsArrayIndex(&index)) {
- HandleScope scope(isolate());
Handle<Object> result = SetElement(receiver, index, value, strict_mode);
- if (result.is_null()) return Failure::Exception();
+ RETURN_IF_EMPTY_HANDLE(isolate(), result);
return *value;
}
// Use specialized code for setting the length of arrays.
if (receiver->IsJSArray()
&& name->Equals(isolate()->heap()->length_symbol())
- && JSArray::cast(*receiver)->AllowsSetElementsLength()) {
+ && Handle<JSArray>::cast(receiver)->AllowsSetElementsLength()) {
#ifdef DEBUG
if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
#endif
- Builtins::Name target = (strict_mode == kStrictMode)
- ? Builtins::kStoreIC_ArrayLength_Strict
- : Builtins::kStoreIC_ArrayLength;
- set_target(isolate()->builtins()->builtin(target));
+ Handle<Code> stub = (strict_mode == kStrictMode)
+ ? isolate()->builtins()->StoreIC_ArrayLength_Strict()
+ : isolate()->builtins()->StoreIC_ArrayLength();
+ set_target(*stub);
return receiver->SetProperty(*name, *value, NONE, strict_mode);
}
// Lookup the property locally in the receiver.
if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
LookupResult lookup(isolate());
- if (LookupForWrite(*receiver, *name, &lookup)) {
+
+ if (LookupForWrite(receiver, name, &lookup)) {
// Generate a stub for this store.
UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
} else {
}
if (receiver->IsJSGlobalProxy()) {
+ // TODO(ulan): find out why we patch this site even with --no-use-ic
// Generate a generic stub that goes to the runtime when we see a global
// proxy as receiver.
- Code* stub = (strict_mode == kStrictMode)
+ Handle<Code> stub = (strict_mode == kStrictMode)
? global_proxy_stub_strict()
: global_proxy_stub();
- if (target() != stub) {
- set_target(stub);
+ if (target() != *stub) {
+ set_target(*stub);
#ifdef DEBUG
TraceIC("StoreIC", name, state, target());
#endif
// Compute the code stub for this store; used for rewriting to
// monomorphic state and making sure that the code stub is in the
// stub cache.
- MaybeObject* maybe_code = NULL;
- Object* code = NULL;
+ Handle<Code> code;
switch (type) {
- case FIELD: {
- maybe_code = isolate()->stub_cache()->ComputeStoreField(
- *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode);
+ case FIELD:
+ code = isolate()->stub_cache()->ComputeStoreField(name,
+ receiver,
+ lookup->GetFieldIndex(),
+ Handle<Map>::null(),
+ strict_mode);
break;
- }
case MAP_TRANSITION: {
if (lookup->GetAttributes() != NONE) return;
- HandleScope scope(isolate());
ASSERT(type == MAP_TRANSITION);
Handle<Map> transition(lookup->GetTransitionMap());
int index = transition->PropertyIndexFor(*name);
- maybe_code = isolate()->stub_cache()->ComputeStoreField(
- *name, *receiver, index, *transition, strict_mode);
+ code = isolate()->stub_cache()->ComputeStoreField(
+ name, receiver, index, transition, strict_mode);
break;
}
- case NORMAL: {
+ case NORMAL:
if (receiver->IsGlobalObject()) {
// The stub generated for the global object picks the value directly
// from the property cell. So the property must be directly on the
// global object.
Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
- JSGlobalPropertyCell* cell =
- JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
- maybe_code = isolate()->stub_cache()->ComputeStoreGlobal(
- *name, *global, cell, strict_mode);
+ Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
+ code = isolate()->stub_cache()->ComputeStoreGlobal(
+ name, global, cell, strict_mode);
} else {
if (lookup->holder() != *receiver) return;
- maybe_code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
+ code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
}
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->setter()) == 0) return;
- maybe_code = isolate()->stub_cache()->ComputeStoreCallback(
- *name, *receiver, callback, strict_mode);
+ code = isolate()->stub_cache()->ComputeStoreCallback(
+ name, receiver, callback, strict_mode);
break;
}
- case INTERCEPTOR: {
+ case INTERCEPTOR:
ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
- maybe_code = isolate()->stub_cache()->ComputeStoreInterceptor(
- *name, *receiver, strict_mode);
+ code = isolate()->stub_cache()->ComputeStoreInterceptor(
+ name, receiver, strict_mode);
break;
- }
default:
return;
}
- // 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.
if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
- set_target(Code::cast(code));
+ set_target(*code);
} else if (state == MONOMORPHIC) {
// Only move to megamorphic if the target changes.
- if (target() != Code::cast(code)) {
+ if (target() != *code) {
set_target((strict_mode == kStrictMode)
? megamorphic_stub_strict()
: megamorphic_stub());
}
} else if (state == MEGAMORPHIC) {
// Update the stub cache.
- isolate()->stub_cache()->Set(*name,
- receiver->map(),
- Code::cast(code));
+ isolate()->stub_cache()->Set(*name, receiver->map(), *code);
}
#ifdef DEBUG
// Used from ic-<arch>.cc.
RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) {
- NoHandleAllocation na;
+ HandleScope scope;
ASSERT(args.length() == 3);
StoreIC ic(isolate);
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
return Isolate::Current()->builtins()->builtin(
Builtins::kStoreIC_Initialize_Strict);
}
- Code* global_proxy_stub() {
- return isolate()->builtins()->builtin(
- Builtins::kStoreIC_GlobalProxy);
+ Handle<Code> global_proxy_stub() {
+ return isolate()->builtins()->StoreIC_GlobalProxy();
}
- Code* global_proxy_stub_strict() {
- return isolate()->builtins()->builtin(
- Builtins::kStoreIC_GlobalProxy_Strict);
+ Handle<Code> global_proxy_stub_strict() {
+ return isolate()->builtins()->StoreIC_GlobalProxy_Strict();
}
static void Clear(Address address, Code* target);
}
-MaybeObject* StubCache::ComputeStoreField(String* name,
- JSObject* receiver,
+Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
+ int index,
+ Handle<Map> transition,
+ Handle<String> name) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileStoreField(*object,
+ index,
+ (transition.is_null()
+ ? NULL
+ : *transition),
+ *name),
+ Code);
+}
+
+
+Handle<Code> StubCache::ComputeStoreField(Handle<String> name,
+ Handle<JSObject> receiver,
int field_index,
- Map* transition,
+ Handle<Map> transition,
StrictModeFlag strict_mode) {
- PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION;
+ PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::STORE_IC, type, strict_mode);
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- StoreStubCompiler compiler(isolate_, strict_mode);
- { MaybeObject* maybe_code =
- compiler.CompileStoreField(receiver, field_index, transition, name);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
- GDBJIT(AddCode(GDBJITInterface::STORE_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);
+
+ StoreStubCompiler compiler(isolate_, strict_mode);
+ Handle<Code> code =
+ compiler.CompileStoreField(receiver, field_index, transition, name);
+ PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
+ GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
}
-MaybeObject* StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
- return isolate_->builtins()->builtin((strict_mode == kStrictMode)
- ? Builtins::kStoreIC_Normal_Strict
- : Builtins::kStoreIC_Normal);
+Handle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
+ return (strict_mode == kStrictMode)
+ ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict()
+ : isolate_->builtins()->Builtins::StoreIC_Normal();
+}
+
+
+Handle<Code> StoreStubCompiler::CompileStoreGlobal(
+ Handle<GlobalObject> object,
+ Handle<JSGlobalPropertyCell> holder,
+ Handle<String> name) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileStoreGlobal(*object, *holder, *name),
+ Code);
}
-MaybeObject* StubCache::ComputeStoreGlobal(String* name,
- GlobalObject* receiver,
- JSGlobalPropertyCell* cell,
+Handle<Code> StubCache::ComputeStoreGlobal(Handle<String> name,
+ Handle<GlobalObject> receiver,
+ Handle<JSGlobalPropertyCell> cell,
StrictModeFlag strict_mode) {
Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::STORE_IC, NORMAL, strict_mode);
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- StoreStubCompiler compiler(isolate_, strict_mode);
- { MaybeObject* maybe_code =
- compiler.CompileStoreGlobal(receiver, cell, name);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
- GDBJIT(AddCode(GDBJITInterface::STORE_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);
+
+ StoreStubCompiler compiler(isolate_, strict_mode);
+ Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name);
+ PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
+ GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
-MaybeObject* StubCache::ComputeStoreCallback(
- String* name,
- JSObject* receiver,
- AccessorInfo* callback,
- StrictModeFlag strict_mode) {
+Handle<Code> StoreStubCompiler::CompileStoreCallback(
+ Handle<JSObject> object,
+ Handle<AccessorInfo> callback,
+ Handle<String> name) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileStoreCallback(*object, *callback, *name),
+ Code);
+}
+
+
+Handle<Code> StubCache::ComputeStoreCallback(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<AccessorInfo> callback,
+ StrictModeFlag strict_mode) {
ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::STORE_IC, CALLBACKS, strict_mode);
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- StoreStubCompiler compiler(isolate_, strict_mode);
- { MaybeObject* maybe_code =
- compiler.CompileStoreCallback(receiver, callback, name);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
- GDBJIT(AddCode(GDBJITInterface::STORE_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);
+
+ StoreStubCompiler compiler(isolate_, strict_mode);
+ Handle<Code> code = compiler.CompileStoreCallback(receiver, callback, name);
+ PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
+ GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
-MaybeObject* StubCache::ComputeStoreInterceptor(
- String* name,
- JSObject* receiver,
- StrictModeFlag strict_mode) {
+Handle<Code> StoreStubCompiler::CompileStoreInterceptor(Handle<JSObject> object,
+ Handle<String> name) {
+ CALL_HEAP_FUNCTION(isolate(),
+ CompileStoreInterceptor(*object, *name),
+ Code);
+}
+
+
+Handle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name,
+ Handle<JSObject> receiver,
+ StrictModeFlag strict_mode) {
Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::STORE_IC, INTERCEPTOR, strict_mode);
- Object* code = receiver->map()->FindInCodeCache(name, flags);
- if (code->IsUndefined()) {
- HandleScope scope(isolate_);
- StoreStubCompiler compiler(isolate_, strict_mode);
- { MaybeObject* maybe_code =
- compiler.CompileStoreInterceptor(receiver, name);
- if (!maybe_code->ToObject(&code)) return maybe_code;
- }
- PROFILE(isolate_,
- CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
- GDBJIT(AddCode(GDBJITInterface::STORE_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);
+
+ StoreStubCompiler compiler(isolate_, strict_mode);
+ Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name);
+ PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
+ GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
+ JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
return code;
}
// ---
- MUST_USE_RESULT MaybeObject* ComputeStoreField(
- String* name,
- JSObject* receiver,
- int field_index,
- Map* transition,
- StrictModeFlag strict_mode);
+ Handle<Code> ComputeStoreField(Handle<String> name,
+ Handle<JSObject> receiver,
+ int field_index,
+ Handle<Map> transition,
+ StrictModeFlag strict_mode);
- MUST_USE_RESULT MaybeObject* ComputeStoreNormal(
- StrictModeFlag strict_mode);
+ Handle<Code> ComputeStoreNormal(StrictModeFlag strict_mode);
- MUST_USE_RESULT MaybeObject* ComputeStoreGlobal(
- String* name,
- GlobalObject* receiver,
- JSGlobalPropertyCell* cell,
- StrictModeFlag strict_mode);
+ Handle<Code> ComputeStoreGlobal(Handle<String> name,
+ Handle<GlobalObject> receiver,
+ Handle<JSGlobalPropertyCell> cell,
+ StrictModeFlag strict_mode);
- MUST_USE_RESULT MaybeObject* ComputeStoreCallback(
- String* name,
- JSObject* receiver,
- AccessorInfo* callback,
- StrictModeFlag strict_mode);
+ Handle<Code> ComputeStoreCallback(Handle<String> name,
+ Handle<JSObject> receiver,
+ Handle<AccessorInfo> callback,
+ StrictModeFlag strict_mode);
- MUST_USE_RESULT MaybeObject* ComputeStoreInterceptor(
- String* name,
- JSObject* receiver,
- StrictModeFlag strict_mode);
+ Handle<Code> ComputeStoreInterceptor(Handle<String> name,
+ Handle<JSObject> receiver,
+ StrictModeFlag strict_mode);
// ---
StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
: StubCompiler(isolate), strict_mode_(strict_mode) { }
+
+ Handle<Code> CompileStoreField(Handle<JSObject> object,
+ int index,
+ Handle<Map> transition,
+ Handle<String> name);
+
MUST_USE_RESULT MaybeObject* CompileStoreField(JSObject* object,
int index,
Map* transition,
String* name);
+ Handle<Code> CompileStoreCallback(Handle<JSObject> object,
+ Handle<AccessorInfo> callback,
+ Handle<String> name);
+
MUST_USE_RESULT MaybeObject* CompileStoreCallback(JSObject* object,
- AccessorInfo* callbacks,
+ AccessorInfo* callback,
String* name);
+ Handle<Code> CompileStoreInterceptor(Handle<JSObject> object,
+ Handle<String> name);
+
MUST_USE_RESULT MaybeObject* CompileStoreInterceptor(JSObject* object,
String* name);
+
+ Handle<Code> CompileStoreGlobal(Handle<GlobalObject> object,
+ Handle<JSGlobalPropertyCell> holder,
+ Handle<String> name);
+
MUST_USE_RESULT MaybeObject* CompileStoreGlobal(GlobalObject* object,
JSGlobalPropertyCell* holder,
String* name);