| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 107338caeeb14dd598e2711aa0e9b2c121c6f91f..be28d23338f70f794c4fc520998bf9a3683a8609 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -1371,17 +1371,17 @@ static bool StoreICableLookup(LookupResult* lookup) {
|
| }
|
|
|
|
|
| -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);
|
| }
|
|
|
| @@ -1422,30 +1422,30 @@ MaybeObject* StoreIC::Store(State state,
|
| // 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 {
|
| @@ -1462,13 +1462,14 @@ MaybeObject* StoreIC::Store(State state,
|
| }
|
|
|
| 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
|
| @@ -1499,77 +1500,70 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
| // 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
|
| @@ -2090,7 +2084,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) {
|
|
|
| // 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]);
|
|
|