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) {
}
+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());
// 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
// 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);
}
// 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()) {
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.
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
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;
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;
// 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]);
}
-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
// 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;
}
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;
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;
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;
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;
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;
}
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;
}
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;
}
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;
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;
}
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;
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;
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;
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;
// 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;
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,
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;
// 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;
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));
}
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));
}
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));
}
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));
}
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));
}
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));
}
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));
}
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
}
-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) {
// 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);
// ---
Isolate* isolate() { return isolate_; }
Heap* heap() { return isolate()->heap(); }
+ Factory* factory() { return isolate()->factory(); }
private:
explicit StubCache(Isolate* isolate);
// 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);
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_;
};
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,
class KeyedLoadStubCompiler: public StubCompiler {
public:
+ explicit KeyedLoadStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
MUST_USE_RESULT MaybeObject* CompileLoadField(String* name,
JSObject* object,
JSObject* holder,
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,
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,
class CallStubCompiler: public StubCompiler {
public:
- CallStubCompiler(int argc,
+ CallStubCompiler(Isolate* isolate,
+ int argc,
Code::Kind kind,
Code::ExtraICState extra_ic_state,
InlineCacheHolderFlag cache_holder);
class ConstructStubCompiler: public StubCompiler {
public:
- explicit ConstructStubCompiler() {}
+ explicit ConstructStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
MUST_USE_RESULT MaybeObject* CompileConstructStub(JSFunction* function);