| Index: src/stub-cache.cc
|
| diff --git a/src/stub-cache.cc b/src/stub-cache.cc
|
| index ac94fffebd0553b34a3fdf315d1220506178b833..9a2ca0256a2d99cb8a29138911820faa16d8512a 100644
|
| --- a/src/stub-cache.cc
|
| +++ b/src/stub-cache.cc
|
| @@ -112,9 +112,9 @@ Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver,
|
| Handle<Code> StubCache::FindIC(Handle<Name> name,
|
| Handle<JSObject> stub_holder,
|
| Code::Kind kind,
|
| - Code::StubType type) {
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - kind, Code::kNoExtraICState, type);
|
| + Code::StubType type,
|
| + Code::ExtraICState extra_ic_state) {
|
| + Code::Flags flags = Code::ComputeMonomorphicFlags(kind, extra_ic_state, type);
|
| Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
| @@ -122,18 +122,14 @@ Handle<Code> StubCache::FindIC(Handle<Name> name,
|
| }
|
|
|
|
|
| -Handle<Code> StubCache::FindStub(Handle<Name> name,
|
| - Handle<JSObject> stub_holder,
|
| - Code::Kind kind,
|
| - Code::StubType type) {
|
| +Handle<Code> StubCache::FindHandler(Handle<Name> name,
|
| + Handle<JSObject> stub_holder,
|
| + Code::Kind kind,
|
| + Code::StubType type,
|
| + Code::ExtraICState extra_ic_state) {
|
| ASSERT(type != Code::NORMAL);
|
| - int extra_flags = -1;
|
| - if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) {
|
| - extra_flags = kind;
|
| - kind = Code::STUB;
|
| - }
|
| Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - kind, Code::kNoExtraICState, type, extra_flags);
|
| + Code::STUB, extra_ic_state, type, kind);
|
| Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
|
| isolate_);
|
| if (probe->IsCode()) return Handle<Code>::cast(probe);
|
| @@ -197,7 +193,7 @@ Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
|
|
|
| // Compile the stub that is either shared for all names or
|
| // name specific if there are global objects involved.
|
| - Handle<Code> handler = FindStub(
|
| + Handle<Code> handler = FindHandler(
|
| cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT);
|
| if (!handler.is_null()) return handler;
|
|
|
| @@ -221,7 +217,7 @@ Handle<Code> StubCache::ComputeLoadField(Handle<Name> name,
|
| }
|
|
|
| Handle<JSObject> stub_holder = StubHolder(receiver, holder);
|
| - Handle<Code> stub = FindStub(
|
| + Handle<Code> stub = FindHandler(
|
| name, stub_holder, Code::LOAD_IC, Code::FIELD);
|
| if (!stub.is_null()) return stub;
|
|
|
| @@ -240,7 +236,7 @@ Handle<Code> StubCache::ComputeLoadCallback(
|
| Handle<ExecutableAccessorInfo> callback) {
|
| ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
|
| Handle<JSObject> stub_holder = StubHolder(receiver, holder);
|
| - Handle<Code> stub = FindStub(
|
| + Handle<Code> stub = FindHandler(
|
| name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
|
| if (!stub.is_null()) return stub;
|
|
|
| @@ -257,7 +253,7 @@ Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name,
|
| Handle<JSObject> holder,
|
| Handle<JSFunction> getter) {
|
| Handle<JSObject> stub_holder = StubHolder(receiver, holder);
|
| - Handle<Code> stub = FindStub(
|
| + Handle<Code> stub = FindHandler(
|
| name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
|
| if (!stub.is_null()) return stub;
|
|
|
| @@ -274,7 +270,7 @@ Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name,
|
| Handle<JSObject> holder,
|
| Handle<JSFunction> value) {
|
| Handle<JSObject> stub_holder = StubHolder(receiver, holder);
|
| - Handle<Code> handler = FindStub(
|
| + Handle<Code> handler = FindHandler(
|
| name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION);
|
| if (!handler.is_null()) return handler;
|
|
|
| @@ -290,7 +286,7 @@ Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name,
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder) {
|
| Handle<JSObject> stub_holder = StubHolder(receiver, holder);
|
| - Handle<Code> stub = FindStub(
|
| + Handle<Code> stub = FindHandler(
|
| name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR);
|
| if (!stub.is_null()) return stub;
|
|
|
| @@ -337,7 +333,7 @@ Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name,
|
| }
|
|
|
| Handle<JSObject> stub_holder = StubHolder(receiver, holder);
|
| - Handle<Code> stub = FindStub(
|
| + Handle<Code> stub = FindHandler(
|
| name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
|
| if (!stub.is_null()) return stub;
|
|
|
| @@ -354,7 +350,7 @@ Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name,
|
| Handle<JSObject> holder,
|
| Handle<JSFunction> value) {
|
| Handle<JSObject> stub_holder = StubHolder(receiver, holder);
|
| - Handle<Code> handler = FindStub(
|
| + Handle<Code> handler = FindHandler(
|
| name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION);
|
| if (!handler.is_null()) return handler;
|
|
|
| @@ -369,7 +365,7 @@ Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name,
|
| Handle<JSObject> receiver,
|
| Handle<JSObject> holder) {
|
| Handle<JSObject> stub_holder = StubHolder(receiver, holder);
|
| - Handle<Code> stub = FindStub(
|
| + Handle<Code> stub = FindHandler(
|
| name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
|
| if (!stub.is_null()) return stub;
|
|
|
| @@ -387,7 +383,7 @@ Handle<Code> StubCache::ComputeKeyedLoadCallback(
|
| Handle<JSObject> holder,
|
| Handle<ExecutableAccessorInfo> callback) {
|
| Handle<JSObject> stub_holder = StubHolder(receiver, holder);
|
| - Handle<Code> stub = FindStub(
|
| + Handle<Code> stub = FindHandler(
|
| name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
|
| if (!stub.is_null()) return stub;
|
|
|
| @@ -405,12 +401,11 @@ Handle<Code> StubCache::ComputeStoreField(Handle<Name> name,
|
| Handle<Map> transition,
|
| StrictModeFlag strict_mode) {
|
| Code::StubType type =
|
| - (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - Code::STORE_IC, strict_mode, type);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| - isolate_);
|
| - if (probe->IsCode()) return Handle<Code>::cast(probe);
|
| + transition.is_null() ? Code::FIELD : Code::MAP_TRANSITION;
|
| +
|
| + Handle<Code> stub = FindIC(
|
| + name, receiver, Code::STORE_IC, type, strict_mode);
|
| + if (!stub.is_null()) return stub;
|
|
|
| StoreStubCompiler compiler(isolate_, strict_mode);
|
| Handle<Code> code =
|
| @@ -473,11 +468,9 @@ Handle<Code> StubCache::ComputeStoreGlobal(Handle<Name> name,
|
| Handle<GlobalObject> receiver,
|
| Handle<JSGlobalPropertyCell> cell,
|
| StrictModeFlag strict_mode) {
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - Code::STORE_IC, strict_mode);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| - isolate_);
|
| - if (probe->IsCode()) return Handle<Code>::cast(probe);
|
| + Handle<Code> stub = FindIC(
|
| + name, receiver, Code::STORE_IC, Code::NORMAL, strict_mode);
|
| + if (!stub.is_null()) return stub;
|
|
|
| StoreStubCompiler compiler(isolate_, strict_mode);
|
| Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name);
|
| @@ -493,11 +486,9 @@ Handle<Code> StubCache::ComputeStoreCallback(
|
| Handle<ExecutableAccessorInfo> callback,
|
| StrictModeFlag strict_mode) {
|
| ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - Code::STORE_IC, strict_mode, Code::CALLBACKS);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| - isolate_);
|
| - if (probe->IsCode()) return Handle<Code>::cast(probe);
|
| + Handle<Code> stub = FindIC(
|
| + name, receiver, Code::STORE_IC, Code::CALLBACKS, strict_mode);
|
| + if (!stub.is_null()) return stub;
|
|
|
| StoreStubCompiler compiler(isolate_, strict_mode);
|
| Handle<Code> code =
|
| @@ -512,11 +503,9 @@ Handle<Code> StubCache::ComputeStoreViaSetter(Handle<Name> name,
|
| Handle<JSObject> holder,
|
| Handle<JSFunction> setter,
|
| StrictModeFlag strict_mode) {
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - Code::STORE_IC, strict_mode, Code::CALLBACKS);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| - isolate_);
|
| - if (probe->IsCode()) return Handle<Code>::cast(probe);
|
| + Handle<Code> stub = FindIC(
|
| + name, receiver, Code::STORE_IC, Code::CALLBACKS, strict_mode);
|
| + if (!stub.is_null()) return stub;
|
|
|
| StoreStubCompiler compiler(isolate_, strict_mode);
|
| Handle<Code> code =
|
| @@ -529,11 +518,9 @@ Handle<Code> StubCache::ComputeStoreViaSetter(Handle<Name> name,
|
| Handle<Code> StubCache::ComputeStoreInterceptor(Handle<Name> name,
|
| Handle<JSObject> receiver,
|
| StrictModeFlag strict_mode) {
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - Code::STORE_IC, strict_mode, Code::INTERCEPTOR);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| - isolate_);
|
| - if (probe->IsCode()) return Handle<Code>::cast(probe);
|
| + Handle<Code> stub = FindIC(
|
| + name, receiver, Code::STORE_IC, Code::INTERCEPTOR, strict_mode);
|
| + if (!stub.is_null()) return stub;
|
|
|
| StoreStubCompiler compiler(isolate_, strict_mode);
|
| Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name);
|
| @@ -548,11 +535,9 @@ Handle<Code> StubCache::ComputeKeyedStoreField(Handle<Name> name,
|
| StrictModeFlag strict_mode) {
|
| Code::StubType type =
|
| (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - Code::KEYED_STORE_IC, strict_mode, type);
|
| - Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
|
| - isolate_);
|
| - if (probe->IsCode()) return Handle<Code>::cast(probe);
|
| + Handle<Code> stub = FindIC(
|
| + name, receiver, Code::KEYED_STORE_IC, type, strict_mode);
|
| + if (!stub.is_null()) return stub;
|
|
|
| KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
|
| Handle<Code> code =
|
| @@ -1452,16 +1437,29 @@ Handle<Code> BaseLoadStubCompiler::CompileLoadField(Handle<JSObject> object,
|
| Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss);
|
|
|
| LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder));
|
| - GenerateTailCall(stub.GetCode(isolate()));
|
| + GenerateTailCall(masm(), stub.GetCode(isolate()));
|
|
|
| __ bind(&miss);
|
| - GenerateLoadMiss(masm(), kind());
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
|
|
| // Return the generated code.
|
| return GetCode(kind(), Code::FIELD, name);
|
| }
|
|
|
|
|
| +// Load a fast property out of a holder object (src). In-object properties
|
| +// are loaded directly otherwise the property is loaded from the properties
|
| +// fixed array.
|
| +void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
|
| + Register dst,
|
| + Register src,
|
| + Handle<JSObject> holder,
|
| + PropertyIndex index) {
|
| + DoGenerateFastPropertyLoad(
|
| + masm, dst, src, index.is_inobject(holder), index.translate(holder));
|
| +}
|
| +
|
| +
|
| Handle<Code> BaseLoadStubCompiler::CompileLoadConstant(
|
| Handle<JSObject> object,
|
| Handle<JSObject> holder,
|
| @@ -1527,7 +1525,7 @@ void BaseLoadStubCompiler::GenerateLoadPostInterceptor(
|
| LoadFieldStub stub(interceptor_reg,
|
| field.is_inobject(holder),
|
| field.translate(holder));
|
| - GenerateTailCall(stub.GetCode(isolate()));
|
| + GenerateTailCall(masm(), stub.GetCode(isolate()));
|
| } else {
|
| // We found FIELD property in prototype chain of interceptor's holder.
|
| // Retrieve a field from field's holder.
|
| @@ -1581,9 +1579,45 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter(
|
| }
|
|
|
|
|
| +Handle<Code> BaseStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
|
| + int index,
|
| + Handle<Map> transition,
|
| + Handle<Name> name) {
|
| + Label miss, miss_restore_name;
|
| +
|
| + GenerateNameCheck(name, this->name(), &miss);
|
| +
|
| + // Generate store field code.
|
| + GenerateStoreField(masm(),
|
| + object,
|
| + index,
|
| + transition,
|
| + name,
|
| + receiver(), this->name(), value(), scratch1(), scratch2(),
|
| + &miss,
|
| + &miss_restore_name);
|
| +
|
| + // Handle store cache miss.
|
| + GenerateRestoreName(masm(), &miss_restore_name, name);
|
| + __ bind(&miss);
|
| + TailCallBuiltin(masm(), MissBuiltin(kind()));
|
| +
|
| + // Return the generated code.
|
| + return GetICCode(kind(),
|
| + transition.is_null() ? Code::FIELD : Code::MAP_TRANSITION,
|
| + name);
|
| +}
|
| +
|
| +
|
| #undef __
|
|
|
|
|
| +void StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) {
|
| + Handle<Code> code(masm->isolate()->builtins()->builtin(name));
|
| + GenerateTailCall(masm, code);
|
| +}
|
| +
|
| +
|
| void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
|
| GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
|
| }
|
| @@ -1594,6 +1628,16 @@ void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
|
| }
|
|
|
|
|
| +void StoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
|
| + GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
|
| +}
|
| +
|
| +
|
| +void KeyedStoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
|
| + GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
|
| +}
|
| +
|
| +
|
| Handle<Code> BaseLoadStubCompiler::GetICCode(Code::Kind kind,
|
| Code::StubType type,
|
| Handle<Name> name,
|
| @@ -1620,6 +1664,32 @@ Handle<Code> BaseLoadStubCompiler::GetCode(Code::Kind kind,
|
| }
|
|
|
|
|
| +Handle<Code> BaseStoreStubCompiler::GetICCode(Code::Kind kind,
|
| + Code::StubType type,
|
| + Handle<Name> name,
|
| + InlineCacheState state) {
|
| + Code::Flags flags = Code::ComputeFlags(
|
| + kind, state, extra_state(), type);
|
| + Handle<Code> code = GetCodeWithFlags(flags, name);
|
| + PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
|
| + JitEvent(name, code);
|
| + return code;
|
| +}
|
| +
|
| +
|
| +Handle<Code> BaseStoreStubCompiler::GetCode(Code::Kind kind,
|
| + Code::StubType type,
|
| + Handle<Name> name) {
|
| + ASSERT(type != Code::NORMAL);
|
| + Code::Flags flags = Code::ComputeFlags(
|
| + Code::STUB, MONOMORPHIC, extra_state(), type, kind);
|
| + Handle<Code> code = GetCodeWithFlags(flags, name);
|
| + PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
|
| + JitEvent(name, code);
|
| + return code;
|
| +}
|
| +
|
| +
|
| void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
|
| CodeHandleList* handlers) {
|
| for (int i = 0; i < receiver_maps->length(); ++i) {
|
| @@ -1648,31 +1718,6 @@ void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
|
| }
|
|
|
|
|
| -Handle<Code> StoreStubCompiler::GetCode(Code::StubType type,
|
| - Handle<Name> name) {
|
| - Code::Flags flags = Code::ComputeMonomorphicFlags(
|
| - Code::STORE_IC, strict_mode_, type);
|
| - Handle<Code> code = GetCodeWithFlags(flags, name);
|
| - PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
|
| - GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
|
| - return code;
|
| -}
|
| -
|
| -
|
| -Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type,
|
| - Handle<Name> name,
|
| - InlineCacheState state) {
|
| - Code::ExtraICState extra_state =
|
| - Code::ComputeExtraICState(store_mode_, strict_mode_);
|
| - Code::Flags flags =
|
| - Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type);
|
| - Handle<Code> code = GetCodeWithFlags(flags, name);
|
| - PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
|
| - GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
|
| - return code;
|
| -}
|
| -
|
| -
|
| Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic(
|
| MapHandleList* receiver_maps) {
|
| // Collect MONOMORPHIC stubs for all |receiver_maps|.
|
| @@ -1696,7 +1741,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic(
|
| elements_kind,
|
| transitioned_map->elements_kind(),
|
| is_js_array,
|
| - strict_mode_,
|
| + strict_mode(),
|
| store_mode_).GetCode(isolate());
|
| } else {
|
| cached_stub = KeyedStoreElementStub(
|
|
|