Handlify upper layers of LoadIC.
authorulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 18 Oct 2011 12:19:18 +0000 (12:19 +0000)
committerulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 18 Oct 2011 12:19:18 +0000 (12:19 +0000)
BUG=
TEST=

Review URL: http://codereview.chromium.org/8337008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9680 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/api.cc
src/handles.cc
src/handles.h
src/ic.cc
src/ic.h
src/objects.cc
src/objects.h
src/runtime.cc
src/stub-cache.cc
src/stub-cache.h

index e39a84f..673f3bd 100644 (file)
@@ -3093,7 +3093,13 @@ static Local<Value> GetPropertyByLookup(i::Isolate* isolate,
   // If the property being looked up is a callback, it can throw
   // an exception.
   EXCEPTION_PREAMBLE(isolate);
-  i::Handle<i::Object> result = i::GetProperty(receiver, name, lookup);
+  PropertyAttributes attributes;
+  i::Handle<i::Object> result = i::Object::GetProperty(isolate,
+                                                       receiver,
+                                                       receiver,
+                                                       lookup,
+                                                       name,
+                                                       &attributes);
   has_pending_exception = result.is_null();
   EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
 
index 57f5d1b..04f950c 100644 (file)
@@ -376,17 +376,6 @@ Handle<Object> GetProperty(Handle<Object> obj,
 }
 
 
-Handle<Object> GetProperty(Handle<JSReceiver> obj,
-                           Handle<String> name,
-                           LookupResult* result) {
-  PropertyAttributes attributes;
-  Isolate* isolate = Isolate::Current();
-  CALL_HEAP_FUNCTION(isolate,
-                     obj->GetProperty(*obj, result, *name, &attributes),
-                     Object);
-}
-
-
 Handle<Object> GetElement(Handle<Object> obj,
                           uint32_t index) {
   Isolate* isolate = Isolate::Current();
index d5521f8..fa27be5 100644 (file)
@@ -246,11 +246,6 @@ Handle<Object> GetProperty(Handle<JSReceiver> obj,
 Handle<Object> GetProperty(Handle<Object> obj,
                            Handle<Object> key);
 
-Handle<Object> GetProperty(Handle<JSReceiver> obj,
-                           Handle<String> name,
-                           LookupResult* result);
-
-
 Handle<Object> GetElement(Handle<Object> obj,
                           uint32_t index);
 
index 9a56f23..947509c 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -371,8 +371,7 @@ static bool HasInterceptorGetter(JSObject* object) {
 static void LookupForRead(Object* object,
                           String* name,
                           LookupResult* lookup) {
-  AssertNoAllocation no_gc;  // pointers must stay valid
-
+  AssertNoAllocation no_gc;
   // Skip all the objects with named interceptors, but
   // without actual getter.
   while (true) {
@@ -408,6 +407,44 @@ static void LookupForRead(Object* object,
 }
 
 
+static void LookupForRead(Handle<Object> object,
+                          Handle<String> name,
+                          LookupResult* lookup) {
+  // 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;
+    }
+
+    Handle<JSObject> holder(lookup->holder());
+    if (HasInterceptorGetter(*holder)) {
+      return;
+    }
+
+    holder->LocalLookupRealNamedProperty(*name, lookup);
+    if (lookup->IsProperty()) {
+      ASSERT(lookup->type() != INTERCEPTOR);
+      return;
+    }
+
+    Handle<Object> proto(holder->GetPrototype());
+    if (proto->IsNull()) {
+      lookup->NotFound();
+      return;
+    }
+
+    object = proto;
+  }
+}
+
+
 Object* CallICBase::TryCallAsFunction(Object* object) {
   HandleScope scope(isolate());
   Handle<Object> target(object, isolate());
@@ -850,53 +887,44 @@ MaybeObject* LoadIC::Load(State state,
     // the underlying string value.  See ECMA-262 15.5.5.1.
     if ((object->IsString() || object->IsStringWrapper()) &&
         name->Equals(isolate()->heap()->length_symbol())) {
-      AssertNoAllocation no_allocation;
-      Code* stub = NULL;
+      Handle<Code> stub;
       if (state == UNINITIALIZED) {
         stub = pre_monomorphic_stub();
       } else if (state == PREMONOMORPHIC) {
-        if (object->IsString()) {
-          stub = isolate()->builtins()->builtin(
-              Builtins::kLoadIC_StringLength);
-        } else {
-          stub = isolate()->builtins()->builtin(
-              Builtins::kLoadIC_StringWrapperLength);
-        }
+        stub = object->IsString()
+            ? isolate()->builtins()->LoadIC_StringLength()
+            : isolate()->builtins()->LoadIC_StringWrapperLength();
       } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
-        stub = isolate()->builtins()->builtin(
-            Builtins::kLoadIC_StringWrapperLength);
+        stub = isolate()->builtins()->LoadIC_StringWrapperLength();
       } else if (state != MEGAMORPHIC) {
         stub = megamorphic_stub();
       }
-      if (stub != NULL) {
-        set_target(stub);
+      if (!stub.is_null()) {
+        set_target(*stub);
 #ifdef DEBUG
         if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
 #endif
       }
       // Get the string if we have a string wrapper object.
-      if (object->IsJSValue()) {
-        return Smi::FromInt(
-            String::cast(Handle<JSValue>::cast(object)->value())->length());
-      }
-      return Smi::FromInt(String::cast(*object)->length());
+      Handle<Object> string = object->IsJSValue()
+          ? Handle<Object>(Handle<JSValue>::cast(object)->value())
+          : object;
+      return Smi::FromInt(String::cast(*string)->length());
     }
 
     // Use specialized code for getting the length of arrays.
     if (object->IsJSArray() &&
         name->Equals(isolate()->heap()->length_symbol())) {
-      AssertNoAllocation no_allocation;
-      Code* stub = NULL;
+      Handle<Code> stub;
       if (state == UNINITIALIZED) {
         stub = pre_monomorphic_stub();
       } else if (state == PREMONOMORPHIC) {
-        stub = isolate()->builtins()->builtin(
-            Builtins::kLoadIC_ArrayLength);
+        stub = isolate()->builtins()->LoadIC_ArrayLength();
       } else if (state != MEGAMORPHIC) {
         stub = megamorphic_stub();
       }
-      if (stub != NULL) {
-        set_target(stub);
+      if (!stub.is_null()) {
+        set_target(*stub);
 #ifdef DEBUG
         if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
 #endif
@@ -907,23 +935,20 @@ MaybeObject* LoadIC::Load(State state,
     // Use specialized code for getting prototype of functions.
     if (object->IsJSFunction() &&
         name->Equals(isolate()->heap()->prototype_symbol()) &&
-        JSFunction::cast(*object)->should_have_prototype()) {
-      { AssertNoAllocation no_allocation;
-        Code* stub = NULL;
-        if (state == UNINITIALIZED) {
-          stub = pre_monomorphic_stub();
-        } else if (state == PREMONOMORPHIC) {
-          stub = isolate()->builtins()->builtin(
-              Builtins::kLoadIC_FunctionPrototype);
-        } else if (state != MEGAMORPHIC) {
-          stub = megamorphic_stub();
-        }
-        if (stub != NULL) {
-          set_target(stub);
+        Handle<JSFunction>::cast(object)->should_have_prototype()) {
+      Handle<Code> stub;
+      if (state == UNINITIALIZED) {
+        stub = pre_monomorphic_stub();
+      } else if (state == PREMONOMORPHIC) {
+        stub = isolate()->builtins()->LoadIC_FunctionPrototype();
+      } else if (state != MEGAMORPHIC) {
+        stub = megamorphic_stub();
+      }
+      if (!stub.is_null()) {
+        set_target(*stub);
 #ifdef DEBUG
-          if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
+        if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
 #endif
-        }
       }
       return Accessors::FunctionGetPrototype(*object, 0);
     }
@@ -936,7 +961,7 @@ MaybeObject* LoadIC::Load(State state,
 
   // Named lookup in the object.
   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()) {
@@ -955,17 +980,15 @@ MaybeObject* LoadIC::Load(State state,
   if (lookup.IsProperty() &&
       (lookup.type() == INTERCEPTOR || lookup.type() == HANDLER)) {
     // 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(isolate(), 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;
   }
 
   // Get the property.
@@ -988,91 +1011,75 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
   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 if (!lookup->IsProperty()) {
     // Nonexistent property. The result is undefined.
-    maybe_code = isolate()->stub_cache()->ComputeLoadNonexistent(*name,
-                                                                 *receiver);
+    code = isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver);
   } else {
     // Compute monomorphic stub.
+    Handle<JSObject> holder(lookup->holder());
     switch (lookup->type()) {
-      case FIELD: {
-        maybe_code = isolate()->stub_cache()->ComputeLoadField(
-            *name,
-            *receiver,
-            lookup->holder(),
-            lookup->GetFieldIndex());
+      case FIELD:
+        code = isolate()->stub_cache()->ComputeLoadField(
+            name, receiver, holder, lookup->GetFieldIndex());
         break;
-      }
       case CONSTANT_FUNCTION: {
-        Object* constant = lookup->GetConstantFunction();
-        maybe_code = isolate()->stub_cache()->ComputeLoadConstant(
-            *name, *receiver, lookup->holder(), constant);
+        Handle<Object> constant(lookup->GetConstantFunction());
+        code = isolate()->stub_cache()->ComputeLoadConstant(
+            name, receiver, holder, constant);
         break;
       }
-      case NORMAL: {
-        if (lookup->holder()->IsGlobalObject()) {
-          GlobalObject* global = GlobalObject::cast(lookup->holder());
-          JSGlobalPropertyCell* cell =
-              JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
-          maybe_code = isolate()->stub_cache()->ComputeLoadGlobal(*name,
-                                                    *receiver,
-                                                    global,
-                                                    cell,
-                                                    lookup->IsDontDelete());
+      case NORMAL:
+        if (holder->IsGlobalObject()) {
+          Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
+          Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
+          code = isolate()->stub_cache()->ComputeLoadGlobal(
+              name, receiver, global, cell, lookup->IsDontDelete());
         } else {
           // There is only one shared stub for loading normalized
           // properties. It does not traverse the prototype chain, so the
           // property must be found in the receiver for the stub to be
           // applicable.
-          if (lookup->holder() != *receiver) return;
-          maybe_code = isolate()->stub_cache()->ComputeLoadNormal();
+          if (!holder.is_identical_to(receiver)) return;
+          code = isolate()->stub_cache()->ComputeLoadNormal();
         }
         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()->ComputeLoadCallback(
-            *name, *receiver, lookup->holder(), callback);
+        code = isolate()->stub_cache()->ComputeLoadCallback(
+            name, receiver, holder, callback);
         break;
       }
-      case INTERCEPTOR: {
-        ASSERT(HasInterceptorGetter(lookup->holder()));
-        maybe_code = isolate()->stub_cache()->ComputeLoadInterceptor(
-            *name, *receiver, lookup->holder());
+      case INTERCEPTOR:
+        ASSERT(HasInterceptorGetter(*holder));
+        code = isolate()->stub_cache()->ComputeLoadInterceptor(
+            name, receiver, holder);
         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 == PREMONOMORPHIC ||
+  if (state == UNINITIALIZED ||
+      state == PREMONOMORPHIC ||
       state == MONOMORPHIC_PROTOTYPE_FAILURE) {
-    set_target(Code::cast(code));
+    set_target(*code);
   } else if (state == MONOMORPHIC) {
-    set_target(megamorphic_stub());
+    set_target(*megamorphic_stub());
   } else if (state == MEGAMORPHIC) {
     // Cache code holding map should be consistent with
     // GenerateMonomorphicCacheProbe.
-    Map* map = JSObject::cast(object->IsJSObject() ? *object :
-                              object->GetPrototype())->map();
-
-    isolate()->stub_cache()->Set(*name, map, Code::cast(code));
+    isolate()->stub_cache()->Set(*name, receiver->map(), *code);
   }
 
 #ifdef DEBUG
@@ -1101,7 +1108,8 @@ MaybeObject* KeyedLoadIC::ComputePolymorphicStub(
     handler_ics.Add(cached_stub);
   }
   Object* object;
-  KeyedLoadStubCompiler compiler;
+  HandleScope scope(isolate());
+  KeyedLoadStubCompiler compiler(isolate());
   MaybeObject* maybe_code = compiler.CompileLoadPolymorphic(receiver_maps,
                                                             &handler_ics);
   if (!maybe_code->ToObject(&object)) return maybe_code;
@@ -1808,7 +1816,8 @@ MaybeObject* KeyedStoreIC::ComputePolymorphicStub(
     transitioned_maps.Add(transitioned_map);
   }
   Object* object;
-  KeyedStoreStubCompiler compiler(strict_mode);
+  HandleScope scope(isolate());
+  KeyedStoreStubCompiler compiler(isolate(), strict_mode);
   MaybeObject* maybe_code = compiler.CompileStorePolymorphic(
       receiver_maps, &handler_ics, &transitioned_maps);
   if (!maybe_code->ToObject(&object)) return maybe_code;
@@ -2052,7 +2061,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
 
 // Used from ic-<arch>.cc.
 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
-  NoHandleAllocation na;
+  HandleScope scope(isolate);
   ASSERT(args.length() == 2);
   LoadIC ic(isolate);
   IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
index ca8447e..115405e 100644 (file)
--- a/src/ic.h
+++ b/src/ic.h
@@ -321,17 +321,15 @@ class LoadIC: public IC {
                     Handle<String> name);
 
   // Stub accessors.
-  Code* megamorphic_stub() {
-    return isolate()->builtins()->builtin(
-        Builtins::kLoadIC_Megamorphic);
+  Handle<Code> megamorphic_stub() {
+    return isolate()->builtins()->LoadIC_Megamorphic();
   }
   static Code* initialize_stub() {
     return Isolate::Current()->builtins()->builtin(
         Builtins::kLoadIC_Initialize);
   }
-  Code* pre_monomorphic_stub() {
-    return isolate()->builtins()->builtin(
-        Builtins::kLoadIC_PreMonomorphic);
+  Handle<Code> pre_monomorphic_stub() {
+    return isolate()->builtins()->LoadIC_PreMonomorphic();
   }
 
   static void Clear(Address address, Code* target);
index bcb5730..9fd936a 100644 (file)
@@ -528,6 +528,19 @@ bool JSObject::IsDirty() {
 }
 
 
+Handle<Object> Object::GetProperty(Isolate* isolate,
+                                   Handle<Object> object,
+                                   Handle<Object> receiver,
+                                   LookupResult* result,
+                                   Handle<String> key,
+                                   PropertyAttributes* attributes) {
+  CALL_HEAP_FUNCTION(
+      isolate,
+      object->GetProperty(*receiver, result, *key, attributes),
+      Object);
+}
+
+
 MaybeObject* Object::GetProperty(Object* receiver,
                                  LookupResult* result,
                                  String* name,
@@ -3117,6 +3130,15 @@ void NormalizedMapCache::Clear() {
 }
 
 
+void JSObject::UpdateMapCodeCache(Isolate* isolate,
+                                  Handle<JSObject> object,
+                                  Handle<String> name,
+                                  Handle<Code> code) {
+  CALL_HEAP_FUNCTION_VOID(isolate,
+                          object->UpdateMapCodeCache(*name, *code));
+}
+
+
 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) {
   if (map()->is_shared()) {
     // Fast case maps are never marked as shared.
index 1a42811..ed9348d 100644 (file)
@@ -912,10 +912,19 @@ class Object : public MaybeObject {
       Object* receiver,
       String* key,
       PropertyAttributes* attributes);
+
+  static Handle<Object> GetProperty(Isolate* isolate,
+                                    Handle<Object> object,
+                                    Handle<Object> receiver,
+                                    LookupResult* result,
+                                    Handle<String> key,
+                                    PropertyAttributes* attributes);
+
   MUST_USE_RESULT MaybeObject* GetProperty(Object* receiver,
                                            LookupResult* result,
                                            String* key,
                                            PropertyAttributes* attributes);
+
   MUST_USE_RESULT MaybeObject* GetPropertyWithDefinedGetter(Object* receiver,
                                                             JSReceiver* getter);
 
@@ -1835,6 +1844,11 @@ class JSObject: public JSReceiver {
   // dictionary.  Returns the backing after conversion.
   MUST_USE_RESULT MaybeObject* NormalizeElements();
 
+  static void UpdateMapCodeCache(Isolate* isolate,
+                                 Handle<JSObject> object,
+                                 Handle<String> name,
+                                 Handle<Code> code);
+
   MUST_USE_RESULT MaybeObject* UpdateMapCodeCache(String* name, Code* code);
 
   // Transform slow named properties to fast variants.
index cb1a463..65f6df8 100644 (file)
@@ -8069,7 +8069,8 @@ static void TrySettingInlineConstructStub(Isolate* isolate,
     prototype = Handle<Object>(function->instance_prototype(), isolate);
   }
   if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
-    ConstructStubCompiler compiler;
+    HandleScope scope(isolate);
+    ConstructStubCompiler compiler(isolate);
     MaybeObject* code = compiler.CompileConstructStub(*function);
     if (!code->IsFailure()) {
       function->shared()->set_construct_stub(
index 67451f2..75e2e94 100644 (file)
@@ -109,8 +109,17 @@ Code* StubCache::Set(String* name, Map* map, Code* code) {
 }
 
 
-MaybeObject* StubCache::ComputeLoadNonexistent(String* name,
-                                               JSObject* receiver) {
+Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name,
+                                                      Handle<JSObject> object,
+                                                      Handle<JSObject> last) {
+  CALL_HEAP_FUNCTION(isolate(),
+                     CompileLoadNonexistent(*name, *object, *last),
+                     Code);
+}
+
+
+Handle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
+                                               Handle<JSObject> receiver) {
   ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties());
   // If no global objects are present in the prototype chain, the load
   // nonexistent IC stub can be shared for all names for a given map
@@ -118,173 +127,181 @@ MaybeObject* StubCache::ComputeLoadNonexistent(String* name,
   // there are global objects involved, we need to check global
   // property cells in the stub and therefore the stub will be
   // specific to the name.
-  String* cache_name = heap()->empty_string();
+  Handle<String> cache_name = factory()->empty_string();
   if (receiver->IsGlobalObject()) cache_name = name;
-  JSObject* last = receiver;
+  Handle<JSObject> last = receiver;
   while (last->GetPrototype() != heap()->null_value()) {
-    last = JSObject::cast(last->GetPrototype());
+    last = Handle<JSObject>(JSObject::cast(last->GetPrototype()));
     if (last->IsGlobalObject()) cache_name = name;
   }
   // Compile the stub that is either shared for all names or
   // name specific if there are global objects involved.
   Code::Flags flags =
       Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
-  Object* code = receiver->map()->FindInCodeCache(cache_name, flags);
-  if (code->IsUndefined()) {
-    LoadStubCompiler compiler;
-    { MaybeObject* maybe_code =
-          compiler.CompileLoadNonexistent(cache_name, receiver, last);
-      if (!maybe_code->ToObject(&code)) return maybe_code;
-    }
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), cache_name));
-    GDBJIT(AddCode(GDBJITInterface::LOAD_IC, cache_name, Code::cast(code)));
-    Object* result;
-    { MaybeObject* maybe_result =
-          receiver->UpdateMapCodeCache(cache_name, Code::cast(code));
-      if (!maybe_result->ToObject(&result)) return maybe_result;
-    }
-  }
+  Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags));
+  if (probe->IsCode()) return Handle<Code>::cast(probe);
+
+  LoadStubCompiler compiler(isolate_);
+  Handle<Code> code =
+      compiler.CompileLoadNonexistent(cache_name, receiver, last);
+  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name));
+  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code));
+  JSObject::UpdateMapCodeCache(isolate_, receiver, cache_name, code);
   return code;
 }
 
 
-MaybeObject* StubCache::ComputeLoadField(String* name,
-                                         JSObject* receiver,
-                                         JSObject* holder,
+Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
+                                                Handle<JSObject> holder,
+                                                int index,
+                                                Handle<String> name) {
+  CALL_HEAP_FUNCTION(isolate(),
+                     CompileLoadField(*object, *holder, index, *name),
+                     Code);
+}
+
+
+Handle<Code> StubCache::ComputeLoadField(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::LOAD_IC, FIELD);
-  Object* code = receiver->map()->FindInCodeCache(name, flags);
-  if (code->IsUndefined()) {
-    LoadStubCompiler compiler;
-    { MaybeObject* maybe_code =
-          compiler.CompileLoadField(receiver, holder, field_index, name);
-      if (!maybe_code->ToObject(&code)) return maybe_code;
-    }
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
-    GDBJIT(AddCode(GDBJITInterface::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);
+
+  LoadStubCompiler compiler(isolate_);
+  Handle<Code> code =
+      compiler.CompileLoadField(receiver, holder, field_index, name);
+  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
+  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
+  JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
   return code;
 }
 
 
-MaybeObject* StubCache::ComputeLoadCallback(String* name,
-                                            JSObject* receiver,
-                                            JSObject* holder,
-                                            AccessorInfo* callback) {
+Handle<Code> LoadStubCompiler::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::ComputeLoadCallback(Handle<String> name,
+                                            Handle<JSObject> receiver,
+                                            Handle<JSObject> holder,
+                                            Handle<AccessorInfo> callback) {
   ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
-  ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
+  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
   Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
-  Object* code = receiver->map()->FindInCodeCache(name, flags);
-  if (code->IsUndefined()) {
-    LoadStubCompiler compiler;
-    { MaybeObject* maybe_code =
-          compiler.CompileLoadCallback(name, receiver, holder, callback);
-      if (!maybe_code->ToObject(&code)) return maybe_code;
-    }
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
-    GDBJIT(AddCode(GDBJITInterface::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);
+
+  LoadStubCompiler compiler(isolate_);
+  Handle<Code> code =
+      compiler.CompileLoadCallback(name, receiver, holder, callback);
+  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
+  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
+  JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
   return code;
 }
 
 
-MaybeObject* StubCache::ComputeLoadConstant(String* name,
-                                            JSObject* receiver,
-                                            JSObject* holder,
-                                            Object* value) {
-  ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
+Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
+                                                   Handle<JSObject> holder,
+                                                   Handle<Object> value,
+                                                   Handle<String> name) {
+  CALL_HEAP_FUNCTION(isolate(),
+                     CompileLoadConstant(*object, *holder, *value, *name),
+                     Code);
+}
+
+
+Handle<Code> StubCache::ComputeLoadConstant(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::LOAD_IC, CONSTANT_FUNCTION);
-  Object* code = receiver->map()->FindInCodeCache(name, flags);
-  if (code->IsUndefined()) {
-    LoadStubCompiler compiler;
-    { MaybeObject* maybe_code =
-          compiler.CompileLoadConstant(receiver, holder, value, name);
-      if (!maybe_code->ToObject(&code)) return maybe_code;
-    }
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
-    GDBJIT(AddCode(GDBJITInterface::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);
+
+  LoadStubCompiler compiler(isolate_);
+  Handle<Code> code =
+        compiler.CompileLoadConstant(receiver, holder, value, name);
+  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
+  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
+  JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
   return code;
 }
 
 
-MaybeObject* StubCache::ComputeLoadInterceptor(String* name,
-                                               JSObject* receiver,
-                                               JSObject* holder) {
-  ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
+Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object,
+                                                      Handle<JSObject> holder,
+                                                      Handle<String> name) {
+  CALL_HEAP_FUNCTION(isolate(),
+                     CompileLoadInterceptor(*object, *holder, *name),
+                     Code);
+}
+
+
+Handle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
+                                               Handle<JSObject> receiver,
+                                               Handle<JSObject> holder) {
+  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
   Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
-  Object* code = receiver->map()->FindInCodeCache(name, flags);
-  if (code->IsUndefined()) {
-    LoadStubCompiler compiler;
-    { MaybeObject* maybe_code =
-          compiler.CompileLoadInterceptor(receiver, holder, name);
-      if (!maybe_code->ToObject(&code)) return maybe_code;
-    }
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
-    GDBJIT(AddCode(GDBJITInterface::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);
+
+  LoadStubCompiler compiler(isolate_);
+  Handle<Code> code =
+        compiler.CompileLoadInterceptor(receiver, holder, name);
+  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
+  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
+  JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
   return code;
 }
 
 
-MaybeObject* StubCache::ComputeLoadNormal() {
-  return isolate_->builtins()->builtin(Builtins::kLoadIC_Normal);
+Handle<Code> StubCache::ComputeLoadNormal() {
+  return isolate_->builtins()->LoadIC_Normal();
 }
 
-
-MaybeObject* StubCache::ComputeLoadGlobal(String* name,
-                                          JSObject* receiver,
-                                          GlobalObject* holder,
-                                          JSGlobalPropertyCell* cell,
+Handle<Code> LoadStubCompiler::CompileLoadGlobal(
+    Handle<JSObject> object,
+    Handle<GlobalObject> holder,
+    Handle<JSGlobalPropertyCell> cell,
+    Handle<String> name,
+    bool is_dont_delete) {
+  CALL_HEAP_FUNCTION(isolate(),
+                     CompileLoadGlobal(*object,
+                                       *holder,
+                                       *cell,
+                                       *name,
+                                       is_dont_delete),
+                     Code);
+}
+Handle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
+                                          Handle<JSObject> receiver,
+                                          Handle<GlobalObject> holder,
+                                          Handle<JSGlobalPropertyCell> cell,
                                           bool is_dont_delete) {
-  ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
+  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
   Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
-  Object* code = receiver->map()->FindInCodeCache(name, flags);
-  if (code->IsUndefined()) {
-    LoadStubCompiler compiler;
-    { MaybeObject* maybe_code = compiler.CompileLoadGlobal(receiver,
-                                                           holder,
-                                                           cell,
-                                                           name,
-                                                           is_dont_delete);
-      if (!maybe_code->ToObject(&code)) return maybe_code;
-    }
-    PROFILE(isolate_,
-            CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
-    GDBJIT(AddCode(GDBJITInterface::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);
+
+  LoadStubCompiler compiler(isolate_);
+  Handle<Code> code =
+      compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
+  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
+  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
+  JSObject::UpdateMapCodeCache(isolate_, receiver, name, code);
   return code;
 }
 
@@ -297,7 +314,8 @@ MaybeObject* StubCache::ComputeKeyedLoadField(String* name,
   Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    KeyedLoadStubCompiler compiler;
+    HandleScope scope(isolate_);
+    KeyedLoadStubCompiler compiler(isolate_);
     { MaybeObject* maybe_code =
           compiler.CompileLoadField(name, receiver, holder, field_index);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -324,7 +342,8 @@ MaybeObject* StubCache::ComputeKeyedLoadConstant(String* name,
       Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    KeyedLoadStubCompiler compiler;
+    HandleScope scope(isolate_);
+    KeyedLoadStubCompiler compiler(isolate_);
     { MaybeObject* maybe_code =
           compiler.CompileLoadConstant(name, receiver, holder, value);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -350,7 +369,8 @@ MaybeObject* StubCache::ComputeKeyedLoadInterceptor(String* name,
       Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    KeyedLoadStubCompiler compiler;
+    HandleScope scope(isolate_);
+    KeyedLoadStubCompiler compiler(isolate_);
     { MaybeObject* maybe_code =
           compiler.CompileLoadInterceptor(receiver, holder, name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -377,7 +397,8 @@ MaybeObject* StubCache::ComputeKeyedLoadCallback(String* name,
       Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    KeyedLoadStubCompiler compiler;
+    HandleScope scope(isolate_);
+    KeyedLoadStubCompiler compiler(isolate_);
     { MaybeObject* maybe_code =
           compiler.CompileLoadCallback(name, receiver, holder, callback);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -403,7 +424,8 @@ MaybeObject* StubCache::ComputeKeyedLoadArrayLength(String* name,
   ASSERT(receiver->IsJSObject());
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    KeyedLoadStubCompiler compiler;
+    HandleScope scope(isolate_);
+    KeyedLoadStubCompiler compiler(isolate_);
     { MaybeObject* maybe_code = compiler.CompileLoadArrayLength(name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
     }
@@ -427,7 +449,8 @@ MaybeObject* StubCache::ComputeKeyedLoadStringLength(String* name,
   Map* map = receiver->map();
   Object* code = map->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    KeyedLoadStubCompiler compiler;
+    HandleScope scope(isolate_);
+    KeyedLoadStubCompiler compiler(isolate_);
     { MaybeObject* maybe_code = compiler.CompileLoadStringLength(name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
     }
@@ -450,7 +473,8 @@ MaybeObject* StubCache::ComputeKeyedLoadFunctionPrototype(
       Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    KeyedLoadStubCompiler compiler;
+    HandleScope scope(isolate_);
+    KeyedLoadStubCompiler compiler(isolate_);
     { MaybeObject* maybe_code = compiler.CompileLoadFunctionPrototype(name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
     }
@@ -477,7 +501,8 @@ MaybeObject* StubCache::ComputeStoreField(String* name,
       Code::STORE_IC, type, strict_mode);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    StoreStubCompiler compiler(strict_mode);
+    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;
@@ -524,12 +549,14 @@ MaybeObject* StubCache::ComputeKeyedLoadOrStoreElement(
   MaybeObject* maybe_new_code = NULL;
   switch (stub_kind) {
     case KeyedIC::LOAD: {
-      KeyedLoadStubCompiler compiler;
+      HandleScope scope(isolate_);
+      KeyedLoadStubCompiler compiler(isolate_);
       maybe_new_code = compiler.CompileLoadElement(receiver_map);
       break;
     }
     case KeyedIC::STORE_NO_TRANSITION: {
-      KeyedStoreStubCompiler compiler(strict_mode);
+      HandleScope scope(isolate_);
+      KeyedStoreStubCompiler compiler(isolate_, strict_mode);
       maybe_new_code = compiler.CompileStoreElement(receiver_map);
       break;
     }
@@ -574,7 +601,8 @@ MaybeObject* StubCache::ComputeStoreGlobal(String* name,
       Code::STORE_IC, NORMAL, strict_mode);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    StoreStubCompiler compiler(strict_mode);
+    HandleScope scope(isolate_);
+    StoreStubCompiler compiler(isolate_, strict_mode);
     { MaybeObject* maybe_code =
           compiler.CompileStoreGlobal(receiver, cell, name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -602,7 +630,8 @@ MaybeObject* StubCache::ComputeStoreCallback(
       Code::STORE_IC, CALLBACKS, strict_mode);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    StoreStubCompiler compiler(strict_mode);
+    HandleScope scope(isolate_);
+    StoreStubCompiler compiler(isolate_, strict_mode);
     { MaybeObject* maybe_code =
           compiler.CompileStoreCallback(receiver, callback, name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -628,7 +657,8 @@ MaybeObject* StubCache::ComputeStoreInterceptor(
       Code::STORE_IC, INTERCEPTOR, strict_mode);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    StoreStubCompiler compiler(strict_mode);
+    HandleScope scope(isolate_);
+    StoreStubCompiler compiler(isolate_, strict_mode);
     { MaybeObject* maybe_code =
           compiler.CompileStoreInterceptor(receiver, name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -656,7 +686,8 @@ MaybeObject* StubCache::ComputeKeyedStoreField(String* name,
       Code::KEYED_STORE_IC, type, strict_mode);
   Object* code = receiver->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    KeyedStoreStubCompiler compiler(strict_mode);
+    HandleScope scope(isolate());
+    KeyedStoreStubCompiler compiler(isolate(), strict_mode);
     { MaybeObject* maybe_code =
           compiler.CompileStoreField(receiver, field_index, transition, name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -712,7 +743,12 @@ MaybeObject* StubCache::ComputeCallConstant(int argc,
     // caches.
     if (!function->is_compiled()) return Failure::InternalError();
     // Compile the stub - only create stubs for fully compiled functions.
-    CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
+    HandleScope scope(isolate_);
+    CallStubCompiler compiler(isolate_,
+                              argc,
+                              kind,
+                              extra_ic_state,
+                              cache_holder);
     { MaybeObject* maybe_code =
           compiler.CompileCallConstant(object, holder, function, name, check);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -759,7 +795,12 @@ MaybeObject* StubCache::ComputeCallField(int argc,
                                                     argc);
   Object* code = map_holder->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
+    HandleScope scope(isolate_);
+    CallStubCompiler compiler(isolate_,
+                              argc,
+                              kind,
+                              extra_ic_state,
+                              cache_holder);
     { MaybeObject* maybe_code =
           compiler.CompileCallField(JSObject::cast(object),
                                     holder,
@@ -808,7 +849,12 @@ MaybeObject* StubCache::ComputeCallInterceptor(
                                                     argc);
   Object* code = map_holder->map()->FindInCodeCache(name, flags);
   if (code->IsUndefined()) {
-    CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
+    HandleScope scope(isolate());
+    CallStubCompiler compiler(isolate(),
+                              argc,
+                              kind,
+                              extra_ic_state,
+                              cache_holder);
     { MaybeObject* maybe_code =
           compiler.CompileCallInterceptor(JSObject::cast(object), holder, name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -864,7 +910,12 @@ MaybeObject* StubCache::ComputeCallGlobal(int argc,
     // internal error which will make sure we do not update any
     // caches.
     if (!function->is_compiled()) return Failure::InternalError();
-    CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
+    HandleScope scope(isolate());
+    CallStubCompiler compiler(isolate(),
+                              argc,
+                              kind,
+                              extra_ic_state,
+                              cache_holder);
     { MaybeObject* maybe_code =
           compiler.CompileCallGlobal(receiver, holder, cell, function, name);
       if (!maybe_code->ToObject(&code)) return maybe_code;
@@ -967,7 +1018,8 @@ MaybeObject* StubCache::ComputeCallInitialize(int argc,
     if (!maybe_probe->ToObject(&probe)) return maybe_probe;
   }
   if (!probe->IsUndefined()) return probe;
-  StubCompiler compiler;
+  HandleScope scope(isolate_);
+  StubCompiler compiler(isolate_);
   return FillCache(isolate_, compiler.CompileCallInitialize(flags));
 }
 
@@ -1002,7 +1054,8 @@ MaybeObject* StubCache::ComputeCallPreMonomorphic(
     if (!maybe_probe->ToObject(&probe)) return maybe_probe;
   }
   if (!probe->IsUndefined()) return probe;
-  StubCompiler compiler;
+  HandleScope scope(isolate_);
+  StubCompiler compiler(isolate_);
   return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags));
 }
 
@@ -1020,7 +1073,8 @@ MaybeObject* StubCache::ComputeCallNormal(int argc,
     if (!maybe_probe->ToObject(&probe)) return maybe_probe;
   }
   if (!probe->IsUndefined()) return probe;
-  StubCompiler compiler;
+  HandleScope scope(isolate_);
+  StubCompiler compiler(isolate_);
   return FillCache(isolate_, compiler.CompileCallNormal(flags));
 }
 
@@ -1037,7 +1091,8 @@ MaybeObject* StubCache::ComputeCallArguments(int argc, Code::Kind kind) {
     if (!maybe_probe->ToObject(&probe)) return maybe_probe;
   }
   if (!probe->IsUndefined()) return probe;
-  StubCompiler compiler;
+  HandleScope scope(isolate_);
+  StubCompiler compiler(isolate_);
   return FillCache(isolate_, compiler.CompileCallArguments(flags));
 }
 
@@ -1056,7 +1111,8 @@ MaybeObject* StubCache::ComputeCallMegamorphic(
     if (!maybe_probe->ToObject(&probe)) return maybe_probe;
   }
   if (!probe->IsUndefined()) return probe;
-  StubCompiler compiler;
+  HandleScope scope(isolate_);
+  StubCompiler compiler(isolate_);
   return FillCache(isolate_, compiler.CompileCallMegamorphic(flags));
 }
 
@@ -1077,7 +1133,8 @@ MaybeObject* StubCache::ComputeCallMiss(int argc,
     if (!maybe_probe->ToObject(&probe)) return maybe_probe;
   }
   if (!probe->IsUndefined()) return probe;
-  StubCompiler compiler;
+  HandleScope scope(isolate_);
+  StubCompiler compiler(isolate_);
   return FillCache(isolate_, compiler.CompileCallMiss(flags));
 }
 
@@ -1098,7 +1155,8 @@ MaybeObject* StubCache::ComputeCallDebugBreak(
     if (!maybe_probe->ToObject(&probe)) return maybe_probe;
   }
   if (!probe->IsUndefined()) return probe;
-  StubCompiler compiler;
+  HandleScope scope(isolate_);
+  StubCompiler compiler(isolate_);
   return FillCache(isolate_, compiler.CompileCallDebugBreak(flags));
 }
 
@@ -1118,7 +1176,8 @@ MaybeObject* StubCache::ComputeCallDebugPrepareStepIn(
     if (!maybe_probe->ToObject(&probe)) return maybe_probe;
   }
   if (!probe->IsUndefined()) return probe;
-  StubCompiler compiler;
+  HandleScope scope(isolate_);
+  StubCompiler compiler(isolate_);
   return FillCache(isolate_, compiler.CompileCallDebugPrepareStepIn(flags));
 }
 #endif
@@ -1704,11 +1763,13 @@ void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
 }
 
 
-CallStubCompiler::CallStubCompiler(int argc,
+CallStubCompiler::CallStubCompiler(Isolate* isolate,
+                                   int argc,
                                    Code::Kind kind,
                                    Code::ExtraICState extra_ic_state,
                                    InlineCacheHolderFlag cache_holder)
-    : arguments_(argc),
+    : StubCompiler(isolate),
+      arguments_(argc),
       kind_(kind),
       extra_ic_state_(extra_ic_state),
       cache_holder_(cache_holder) {
index d9ec88f..3fc762a 100644 (file)
@@ -76,41 +76,35 @@ class StubCache {
 
   // Computes the right stub matching. Inserts the result in the
   // cache before returning.  This might compile a stub if needed.
-  MUST_USE_RESULT MaybeObject* ComputeLoadNonexistent(
-      String* name,
-      JSObject* receiver);
-
-  MUST_USE_RESULT MaybeObject* ComputeLoadField(String* name,
-                                                JSObject* receiver,
-                                                JSObject* holder,
-                                                int field_index);
-
-  MUST_USE_RESULT MaybeObject* ComputeLoadCallback(
-      String* name,
-      JSObject* receiver,
-      JSObject* holder,
-      AccessorInfo* callback);
+  Handle<Code> ComputeLoadNonexistent(Handle<String> name,
+                                      Handle<JSObject> receiver);
 
-  MUST_USE_RESULT MaybeObject* ComputeLoadConstant(String* name,
-                                                   JSObject* receiver,
-                                                   JSObject* holder,
-                                                   Object* value);
+  Handle<Code> ComputeLoadField(Handle<String> name,
+                                Handle<JSObject> receiver,
+                                Handle<JSObject> holder,
+                                int field_index);
 
-  MUST_USE_RESULT MaybeObject* ComputeLoadInterceptor(
-      String* name,
-      JSObject* receiver,
-      JSObject* holder);
+  Handle<Code> ComputeLoadCallback(Handle<String> name,
+                                   Handle<JSObject> receiver,
+                                   Handle<JSObject> holder,
+                                   Handle<AccessorInfo> callback);
 
-  MUST_USE_RESULT MaybeObject* ComputeLoadNormal();
+  Handle<Code> ComputeLoadConstant(Handle<String> name,
+                                   Handle<JSObject> receiver,
+                                   Handle<JSObject> holder,
+                                   Handle<Object> value);
 
+  Handle<Code> ComputeLoadInterceptor(Handle<String> name,
+                                      Handle<JSObject> receiver,
+                                      Handle<JSObject> holder);
 
-  MUST_USE_RESULT MaybeObject* ComputeLoadGlobal(
-      String* name,
-      JSObject* receiver,
-      GlobalObject* holder,
-      JSGlobalPropertyCell* cell,
-      bool is_dont_delete);
+  Handle<Code> ComputeLoadNormal();
 
+  Handle<Code> ComputeLoadGlobal(Handle<String> name,
+                                 Handle<JSObject> receiver,
+                                 Handle<GlobalObject> holder,
+                                 Handle<JSGlobalPropertyCell> cell,
+                                 bool is_dont_delete);
 
   // ---
 
@@ -330,6 +324,7 @@ class StubCache {
 
   Isolate* isolate() { return isolate_; }
   Heap* heap() { return isolate()->heap(); }
+  Factory* factory() { return isolate()->factory(); }
 
  private:
   explicit StubCache(Isolate* isolate);
@@ -410,8 +405,8 @@ DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor);
 // The stub compiler compiles stubs for the stub cache.
 class StubCompiler BASE_EMBEDDED {
  public:
-  StubCompiler()
-      : scope_(), masm_(Isolate::Current(), NULL, 256), failure_(NULL) { }
+  explicit StubCompiler(Isolate* isolate)
+      : isolate_(isolate), masm_(isolate, NULL, 256), failure_(NULL) { }
 
   MUST_USE_RESULT MaybeObject* CompileCallInitialize(Code::Flags flags);
   MUST_USE_RESULT MaybeObject* CompileCallPreMonomorphic(Code::Flags flags);
@@ -567,12 +562,12 @@ class StubCompiler BASE_EMBEDDED {
                                     String* name,
                                     LookupResult* lookup);
 
-  Isolate* isolate() { return scope_.isolate(); }
+  Isolate* isolate() { return isolate_; }
   Heap* heap() { return isolate()->heap(); }
   Factory* factory() { return isolate()->factory(); }
 
  private:
-  HandleScope scope_;
+  Isolate* isolate_;
   MacroAssembler masm_;
   Failure* failure_;
 };
@@ -580,29 +575,60 @@ class StubCompiler BASE_EMBEDDED {
 
 class LoadStubCompiler: public StubCompiler {
  public:
+  explicit LoadStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
+
+  Handle<Code> CompileLoadNonexistent(Handle<String> name,
+                                      Handle<JSObject> object,
+                                      Handle<JSObject> last);
+
   MUST_USE_RESULT MaybeObject* CompileLoadNonexistent(String* name,
                                                       JSObject* object,
                                                       JSObject* last);
 
+  Handle<Code> CompileLoadField(Handle<JSObject> object,
+                                Handle<JSObject> holder,
+                                int index,
+                                Handle<String> name);
+
   MUST_USE_RESULT MaybeObject* CompileLoadField(JSObject* object,
                                                 JSObject* holder,
                                                 int index,
                                                 String* name);
 
+  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<JSObject> object,
+                                   Handle<JSObject> holder,
+                                   Handle<Object> value,
+                                   Handle<String> name);
+
   MUST_USE_RESULT MaybeObject* CompileLoadConstant(JSObject* object,
                                                    JSObject* holder,
                                                    Object* value,
                                                    String* name);
 
+  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> CompileLoadGlobal(Handle<JSObject> object,
+                                 Handle<GlobalObject> holder,
+                                 Handle<JSGlobalPropertyCell> cell,
+                                 Handle<String> name,
+                                 bool is_dont_delete);
+
   MUST_USE_RESULT MaybeObject* CompileLoadGlobal(JSObject* object,
                                                  GlobalObject* holder,
                                                  JSGlobalPropertyCell* cell,
@@ -616,6 +642,7 @@ class LoadStubCompiler: public StubCompiler {
 
 class KeyedLoadStubCompiler: public StubCompiler {
  public:
+  explicit KeyedLoadStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
   MUST_USE_RESULT MaybeObject* CompileLoadField(String* name,
                                                 JSObject* object,
                                                 JSObject* holder,
@@ -663,8 +690,8 @@ class KeyedLoadStubCompiler: public StubCompiler {
 
 class StoreStubCompiler: public StubCompiler {
  public:
-  explicit StoreStubCompiler(StrictModeFlag strict_mode)
-    : strict_mode_(strict_mode) { }
+  StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
+    : StubCompiler(isolate), strict_mode_(strict_mode) { }
 
   MUST_USE_RESULT MaybeObject* CompileStoreField(JSObject* object,
                                                  int index,
@@ -690,8 +717,8 @@ class StoreStubCompiler: public StubCompiler {
 
 class KeyedStoreStubCompiler: public StubCompiler {
  public:
-  explicit KeyedStoreStubCompiler(StrictModeFlag strict_mode)
-    : strict_mode_(strict_mode) { }
+  KeyedStoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
+    : StubCompiler(isolate), strict_mode_(strict_mode) { }
 
   MUST_USE_RESULT MaybeObject* CompileStoreField(JSObject* object,
                                                  int index,
@@ -742,7 +769,8 @@ class CallOptimization;
 
 class CallStubCompiler: public StubCompiler {
  public:
-  CallStubCompiler(int argc,
+  CallStubCompiler(Isolate* isolate,
+                   int argc,
                    Code::Kind kind,
                    Code::ExtraICState extra_ic_state,
                    InlineCacheHolderFlag cache_holder);
@@ -835,7 +863,7 @@ class CallStubCompiler: public StubCompiler {
 
 class ConstructStubCompiler: public StubCompiler {
  public:
-  explicit ConstructStubCompiler() {}
+  explicit ConstructStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
 
   MUST_USE_RESULT MaybeObject* CompileConstructStub(JSFunction* function);