Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(668)

Unified Diff: src/ic/ic-compiler.cc

Issue 483683005: Move IC code into a subdir and move ic-compilation related code from stub-cache into ic-compiler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix BUILD.gn Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic/ic-compiler.h ('k') | src/ic/ic-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic/ic-compiler.cc
diff --git a/src/stub-cache.cc b/src/ic/ic-compiler.cc
similarity index 73%
rename from src/stub-cache.cc
rename to src/ic/ic-compiler.cc
index 32ff8d1460ecd5da4b129ffe7173de72bdd78f81..05a0a6ee95cdd688d21137342140653ea7b70595 100644
--- a/src/stub-cache.cc
+++ b/src/ic/ic-compiler.cc
@@ -1,112 +1,23 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
+// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/v8.h"
-#include "src/api.h"
-#include "src/arguments.h"
-#include "src/ast.h"
-#include "src/code-stubs.h"
-#include "src/cpu-profiler.h"
-#include "src/gdb-jit.h"
-#include "src/ic-inl.h"
-#include "src/stub-cache.h"
-#include "src/type-info.h"
-#include "src/vm-state-inl.h"
+#include "src/ic/ic-inl.h"
+#include "src/ic/ic-compiler.h"
+
namespace v8 {
namespace internal {
-// -----------------------------------------------------------------------
-// StubCache implementation.
-
-
-StubCache::StubCache(Isolate* isolate)
- : isolate_(isolate) { }
-
-
-void StubCache::Initialize() {
- DCHECK(IsPowerOf2(kPrimaryTableSize));
- DCHECK(IsPowerOf2(kSecondaryTableSize));
- Clear();
-}
-
-
-static Code::Flags CommonStubCacheChecks(Name* name, Map* map,
- Code::Flags flags) {
- flags = Code::RemoveTypeAndHolderFromFlags(flags);
-
- // Validate that the name does not move on scavenge, and that we
- // can use identity checks instead of structural equality checks.
- DCHECK(!name->GetHeap()->InNewSpace(name));
- DCHECK(name->IsUniqueName());
-
- // The state bits are not important to the hash function because the stub
- // cache only contains handlers. Make sure that the bits are the least
- // significant so they will be the ones masked out.
- DCHECK_EQ(Code::HANDLER, Code::ExtractKindFromFlags(flags));
- STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1);
-
- // Make sure that the code type and cache holder are not included in the hash.
- DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
- DCHECK(Code::ExtractCacheHolderFromFlags(flags) == 0);
-
- return flags;
-}
-
-
-Code* StubCache::Set(Name* name, Map* map, Code* code) {
- Code::Flags flags = CommonStubCacheChecks(name, map, code->flags());
-
- // Compute the primary entry.
- int primary_offset = PrimaryOffset(name, flags, map);
- Entry* primary = entry(primary_, primary_offset);
- Code* old_code = primary->value;
-
- // If the primary entry has useful data in it, we retire it to the
- // secondary cache before overwriting it.
- if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) {
- Map* old_map = primary->map;
- Code::Flags old_flags =
- Code::RemoveTypeAndHolderFromFlags(old_code->flags());
- int seed = PrimaryOffset(primary->key, old_flags, old_map);
- int secondary_offset = SecondaryOffset(primary->key, old_flags, seed);
- Entry* secondary = entry(secondary_, secondary_offset);
- *secondary = *primary;
- }
-
- // Update primary cache.
- primary->key = name;
- primary->value = code;
- primary->map = map;
- isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
- return code;
-}
-
-
-Code* StubCache::Get(Name* name, Map* map, Code::Flags flags) {
- flags = CommonStubCacheChecks(name, map, flags);
- int primary_offset = PrimaryOffset(name, flags, map);
- Entry* primary = entry(primary_, primary_offset);
- if (primary->key == name && primary->map == map) {
- return primary->value;
- }
- int secondary_offset = SecondaryOffset(name, flags, primary_offset);
- Entry* secondary = entry(secondary_, secondary_offset);
- if (secondary->key == name && secondary->map == map) {
- return secondary->value;
- }
- return NULL;
-}
-
Handle<Code> PropertyICCompiler::Find(Handle<Name> name,
Handle<Map> stub_holder, Code::Kind kind,
ExtraICState extra_state,
CacheHolderFlag cache_holder) {
- Code::Flags flags = Code::ComputeMonomorphicFlags(
- kind, extra_state, cache_holder);
+ Code::Flags flags =
+ Code::ComputeMonomorphicFlags(kind, extra_state, cache_holder);
Object* probe = stub_holder->FindInCodeCache(*name, flags);
if (probe->IsCode()) return handle(Code::cast(probe));
return Handle<Code>::null();
@@ -261,22 +172,14 @@ Handle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphic(
compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode);
Map::UpdateCodeCache(receiver_map, name, code);
- DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state())
- == store_mode);
+ DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) ==
+ store_mode);
return code;
}
#define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)
-static void FillCache(Isolate* isolate, Handle<Code> code) {
- Handle<UnseededNumberDictionary> dictionary =
- UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
- code->flags(),
- code);
- isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
-}
-
Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind,
ExtraICState state) {
@@ -292,6 +195,13 @@ Code* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind,
}
+static void FillCache(Isolate* isolate, Handle<Code> code) {
+ Handle<UnseededNumberDictionary> dictionary = UnseededNumberDictionary::Set(
+ isolate->factory()->non_monomorphic_cache(), code->flags(), code);
+ isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
+}
+
+
Handle<Code> PropertyICCompiler::ComputeLoad(Isolate* isolate,
InlineCacheState ic_state,
ExtraICState extra_state) {
@@ -417,8 +327,8 @@ Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic(
store_mode == STORE_NO_TRANSITION_HANDLE_COW);
Handle<PolymorphicCodeCache> cache =
isolate->factory()->polymorphic_code_cache();
- ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState(
- strict_mode, store_mode);
+ ExtraICState extra_state =
+ KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
Code::Flags flags =
Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
Handle<Object> probe = cache->Lookup(receiver_maps, flags);
@@ -432,227 +342,10 @@ Handle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic(
}
-void StubCache::Clear() {
- Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
- for (int i = 0; i < kPrimaryTableSize; i++) {
- primary_[i].key = isolate()->heap()->empty_string();
- primary_[i].map = NULL;
- primary_[i].value = empty;
- }
- for (int j = 0; j < kSecondaryTableSize; j++) {
- secondary_[j].key = isolate()->heap()->empty_string();
- secondary_[j].map = NULL;
- secondary_[j].value = empty;
- }
-}
-
-
-void StubCache::CollectMatchingMaps(SmallMapList* types,
- Handle<Name> name,
- Code::Flags flags,
- Handle<Context> native_context,
- Zone* zone) {
- for (int i = 0; i < kPrimaryTableSize; i++) {
- if (primary_[i].key == *name) {
- Map* map = primary_[i].map;
- // Map can be NULL, if the stub is constant function call
- // with a primitive receiver.
- if (map == NULL) continue;
-
- int offset = PrimaryOffset(*name, flags, map);
- if (entry(primary_, offset) == &primary_[i] &&
- !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
- types->AddMapIfMissing(Handle<Map>(map), zone);
- }
- }
- }
-
- for (int i = 0; i < kSecondaryTableSize; i++) {
- if (secondary_[i].key == *name) {
- Map* map = secondary_[i].map;
- // Map can be NULL, if the stub is constant function call
- // with a primitive receiver.
- if (map == NULL) continue;
-
- // Lookup in primary table and skip duplicates.
- int primary_offset = PrimaryOffset(*name, flags, map);
-
- // Lookup in secondary table and add matches.
- int offset = SecondaryOffset(*name, flags, primary_offset);
- if (entry(secondary_, offset) == &secondary_[i] &&
- !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
- types->AddMapIfMissing(Handle<Map>(map), zone);
- }
- }
- }
-}
-
-
-// ------------------------------------------------------------------------
-// StubCompiler implementation.
-
-
-RUNTIME_FUNCTION(StoreCallbackProperty) {
- Handle<JSObject> receiver = args.at<JSObject>(0);
- Handle<JSObject> holder = args.at<JSObject>(1);
- Handle<ExecutableAccessorInfo> callback = args.at<ExecutableAccessorInfo>(2);
- Handle<Name> name = args.at<Name>(3);
- Handle<Object> value = args.at<Object>(4);
- HandleScope scope(isolate);
-
- DCHECK(callback->IsCompatibleReceiver(*receiver));
-
- Address setter_address = v8::ToCData<Address>(callback->setter());
- v8::AccessorNameSetterCallback fun =
- FUNCTION_CAST<v8::AccessorNameSetterCallback>(setter_address);
- DCHECK(fun != NULL);
-
- LOG(isolate, ApiNamedPropertyAccess("store", *receiver, *name));
- PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver,
- *holder);
- custom_args.Call(fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- return *value;
-}
-
-
-/**
- * Attempts to load a property with an interceptor (which must be present),
- * but doesn't search the prototype chain.
- *
- * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
- * provide any value for the given name.
- */
-RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) {
- DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
- Handle<Name> name_handle =
- args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
- Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(
- NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex);
-
- // TODO(rossberg): Support symbols in the API.
- if (name_handle->IsSymbol())
- return isolate->heap()->no_interceptor_result_sentinel();
- Handle<String> name = Handle<String>::cast(name_handle);
-
- Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
- v8::NamedPropertyGetterCallback getter =
- FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
- DCHECK(getter != NULL);
-
- Handle<JSObject> receiver =
- args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
- Handle<JSObject> holder =
- args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
- PropertyCallbackArguments callback_args(
- isolate, interceptor_info->data(), *receiver, *holder);
- {
- // Use the interceptor getter.
- HandleScope scope(isolate);
- v8::Handle<v8::Value> r =
- callback_args.Call(getter, v8::Utils::ToLocal(name));
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- if (!r.IsEmpty()) {
- Handle<Object> result = v8::Utils::OpenHandle(*r);
- result->VerifyApiCallResultType();
- return *v8::Utils::OpenHandle(*r);
- }
- }
-
- return isolate->heap()->no_interceptor_result_sentinel();
-}
-
-
-static Object* ThrowReferenceError(Isolate* isolate, Name* name) {
- // If the load is non-contextual, just return the undefined result.
- // Note that both keyed and non-keyed loads may end up here.
- HandleScope scope(isolate);
- LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
- if (ic.contextual_mode() != CONTEXTUAL) {
- return isolate->heap()->undefined_value();
- }
-
- // Throw a reference error.
- Handle<Name> name_handle(name);
- Handle<Object> error =
- isolate->factory()->NewReferenceError("not_defined",
- HandleVector(&name_handle, 1));
- return isolate->Throw(*error);
-}
-
-
-/**
- * Loads a property with an interceptor performing post interceptor
- * lookup if interceptor failed.
- */
-RUNTIME_FUNCTION(LoadPropertyWithInterceptor) {
- HandleScope scope(isolate);
- DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
- Handle<Name> name =
- args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
- Handle<JSObject> receiver =
- args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
- Handle<JSObject> holder =
- args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
-
- Handle<Object> result;
- LookupIterator it(receiver, name, holder);
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, JSObject::GetProperty(&it));
-
- if (it.IsFound()) return *result;
-
- return ThrowReferenceError(isolate, Name::cast(args[0]));
-}
-
-
-RUNTIME_FUNCTION(StorePropertyWithInterceptor) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 3);
- StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
- Handle<JSObject> receiver = args.at<JSObject>(0);
- Handle<Name> name = args.at<Name>(1);
- Handle<Object> value = args.at<Object>(2);
-#ifdef DEBUG
- PrototypeIterator iter(isolate, receiver,
- PrototypeIterator::START_AT_RECEIVER);
- bool found = false;
- while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
- Handle<Object> current = PrototypeIterator::GetCurrent(iter);
- if (current->IsJSObject() &&
- Handle<JSObject>::cast(current)->HasNamedInterceptor()) {
- found = true;
- break;
- }
- }
- DCHECK(found);
-#endif
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- JSObject::SetProperty(receiver, name, value, ic.strict_mode()));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(LoadElementWithInterceptor) {
- HandleScope scope(isolate);
- Handle<JSObject> receiver = args.at<JSObject>(0);
- DCHECK(args.smi_at(1) >= 0);
- uint32_t index = args.smi_at(1);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- JSObject::GetElementWithInterceptor(receiver, receiver, index));
- return *result;
-}
-
-
Handle<Code> PropertyICCompiler::CompileLoadInitialize(Code::Flags flags) {
LoadIC::GenerateInitialize(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize");
- PROFILE(isolate(),
- CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0));
+ PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0));
return code;
}
@@ -669,8 +362,7 @@ Handle<Code> PropertyICCompiler::CompileLoadPreMonomorphic(Code::Flags flags) {
Handle<Code> PropertyICCompiler::CompileLoadMegamorphic(Code::Flags flags) {
LoadIC::GenerateMegamorphic(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadMegamorphic");
- PROFILE(isolate(),
- CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
+ PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_MEGAMORPHIC_TAG, *code, 0));
return code;
}
@@ -678,8 +370,7 @@ Handle<Code> PropertyICCompiler::CompileLoadMegamorphic(Code::Flags flags) {
Handle<Code> PropertyICCompiler::CompileStoreInitialize(Code::Flags flags) {
StoreIC::GenerateInitialize(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize");
- PROFILE(isolate(),
- CodeCreateEvent(Logger::STORE_INITIALIZE_TAG, *code, 0));
+ PROFILE(isolate(), CodeCreateEvent(Logger::STORE_INITIALIZE_TAG, *code, 0));
return code;
}
@@ -698,8 +389,7 @@ Handle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) {
StrictMode strict_mode = StoreIC::GetStrictMode(extra_state);
StoreIC::GenerateRuntimeSetProperty(masm(), strict_mode);
Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric");
- PROFILE(isolate(),
- CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0));
+ PROFILE(isolate(), CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0));
return code;
}
@@ -707,8 +397,7 @@ Handle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) {
Handle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) {
StoreIC::GenerateMegamorphic(masm());
Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic");
- PROFILE(isolate(),
- CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
+ PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
return code;
}
@@ -736,8 +425,9 @@ Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
Handle<Name> name) {
return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
- ? GetCodeWithFlags(flags, Handle<String>::cast(name)->ToCString().get())
- : GetCodeWithFlags(flags, NULL);
+ ? GetCodeWithFlags(flags,
+ Handle<String>::cast(name)->ToCString().get())
+ : GetCodeWithFlags(flags, NULL);
}
@@ -762,8 +452,8 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
}
if (check_type == CHECK_ALL_MAPS) {
- GenerateDirectLoadGlobalFunctionPrototype(
- masm(), function_index, scratch1(), miss);
+ GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index,
+ scratch1(), miss);
Object* function = isolate()->native_context()->get(function_index);
Object* prototype = JSFunction::cast(function)->instance_prototype();
set_type_for_object(handle(prototype, isolate()));
@@ -885,9 +575,8 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
DCHECK(call_optimization.is_simple_api_call());
Frontend(receiver(), name);
Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
- GenerateFastApiCall(
- masm(), call_optimization, receiver_map,
- receiver(), scratch1(), false, 0, NULL);
+ GenerateFastApiCall(masm(), call_optimization, receiver_map, receiver(),
+ scratch1(), false, 0, NULL);
return GetCode(kind(), Code::FAST, name);
}
@@ -1033,10 +722,9 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
Handle<JSObject> object, Handle<Name> name,
const CallOptimization& call_optimization) {
Frontend(receiver(), name);
- Register values[] = { value() };
- GenerateFastApiCall(
- masm(), call_optimization, handle(object->map()),
- receiver(), scratch1(), true, 1, values);
+ Register values[] = {value()};
+ GenerateFastApiCall(masm(), call_optimization, handle(object->map()),
+ receiver(), scratch1(), true, 1, values);
return GetCode(kind(), Code::FAST, name);
}
@@ -1198,8 +886,7 @@ CallOptimization::CallOptimization(Handle<JSFunction> function) {
Handle<JSObject> CallOptimization::LookupHolderOfExpectedType(
- Handle<Map> object_map,
- HolderLookup* holder_lookup) const {
+ Handle<Map> object_map, HolderLookup* holder_lookup) const {
DCHECK(is_simple_api_call());
if (!object_map->IsJSObjectMap()) {
*holder_lookup = kHolderNotFound;
@@ -1231,8 +918,7 @@ bool CallOptimization::IsCompatibleReceiver(Handle<Object> receiver,
if (!receiver->IsJSObject()) return false;
Handle<Map> map(JSObject::cast(*receiver)->map());
HolderLookup holder_lookup;
- Handle<JSObject> api_holder =
- LookupHolderOfExpectedType(map, &holder_lookup);
+ Handle<JSObject> api_holder = LookupHolderOfExpectedType(map, &holder_lookup);
switch (holder_lookup) {
case kHolderNotFound:
return false;
@@ -1286,14 +972,12 @@ void CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) {
Handle<SignatureInfo>(SignatureInfo::cast(info->signature()));
if (!signature->args()->IsUndefined()) return;
if (!signature->receiver()->IsUndefined()) {
- expected_receiver_type_ =
- Handle<FunctionTemplateInfo>(
- FunctionTemplateInfo::cast(signature->receiver()));
+ expected_receiver_type_ = Handle<FunctionTemplateInfo>(
+ FunctionTemplateInfo::cast(signature->receiver()));
}
}
is_simple_api_call_ = true;
}
-
-
-} } // namespace v8::internal
+}
+} // namespace v8::internal
« no previous file with comments | « src/ic/ic-compiler.h ('k') | src/ic/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698