Index: src/stub-cache.h |
diff --git a/src/stub-cache.h b/src/stub-cache.h |
index 7851a2bc5c18a335d5e30f0fd6e884c8a89f3209..a3bfa42e6e0af0833c8e29b23e7c6ccbf2d5e488 100644 |
--- a/src/stub-cache.h |
+++ b/src/stub-cache.h |
@@ -17,13 +17,10 @@ namespace v8 { |
namespace internal { |
-// The stub cache is used for megamorphic calls and property accesses. |
-// It maps (map, name, type)->Code* |
- |
-// The design of the table uses the inline cache stubs used for |
-// mono-morphic calls. The beauty of this, we do not have to |
-// invalidate the cache whenever a prototype map is changed. The stub |
-// validates the map chain as in the mono-morphic case. |
+// The stub cache is used for megamorphic property accesses. |
+// It maps (map, name, type) to property access handlers. The cache does not |
+// need explicit invalidation when a prototype chain is modified, since the |
+// handlers verify the chain. |
class CallOptimization; |
@@ -53,64 +50,17 @@ class StubCache { |
}; |
void Initialize(); |
- |
- Handle<Code> ComputeMonomorphicIC(Code::Kind kind, |
- Handle<Name> name, |
- Handle<HeapType> type, |
- Handle<Code> handler, |
- ExtraICState extra_ic_state); |
- |
- Handle<Code> ComputeLoadNonexistent(Handle<Name> name, Handle<HeapType> type); |
- |
- Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map); |
- |
- Handle<Code> ComputeKeyedStoreElement(Handle<Map> receiver_map, |
- StrictMode strict_mode, |
- KeyedAccessStoreMode store_mode); |
- |
- // --- |
- |
- Handle<Code> ComputeLoad(InlineCacheState ic_state, ExtraICState extra_state); |
- Handle<Code> ComputeStore(InlineCacheState ic_state, |
- ExtraICState extra_state); |
- |
- // --- |
- |
- Handle<Code> ComputeCompareNil(Handle<Map> receiver_map, |
- CompareNilICStub* stub); |
- |
- // --- |
- |
- Handle<Code> ComputeLoadElementPolymorphic(MapHandleList* receiver_maps); |
- Handle<Code> ComputeStoreElementPolymorphic(MapHandleList* receiver_maps, |
- KeyedAccessStoreMode store_mode, |
- StrictMode strict_mode); |
- |
- Handle<Code> ComputePolymorphicIC(Code::Kind kind, |
- TypeHandleList* types, |
- CodeHandleList* handlers, |
- int number_of_valid_maps, |
- Handle<Name> name, |
- ExtraICState extra_ic_state); |
- |
- // Finds the Code object stored in the Heap::non_monomorphic_cache(). |
- Code* FindPreMonomorphicIC(Code::Kind kind, ExtraICState extra_ic_state); |
- |
- // Update cache for entry hash(name, map). |
+ // Access cache for entry hash(name, map). |
Code* Set(Name* name, Map* map, Code* code); |
- |
Code* Get(Name* name, Map* map, Code::Flags flags); |
- |
// Clear the lookup table (@ mark compact collection). |
void Clear(); |
- |
// Collect all maps that match the name and flags. |
void CollectMatchingMaps(SmallMapList* types, |
Handle<Name> name, |
Code::Flags flags, |
Handle<Context> native_context, |
Zone* zone); |
- |
// Generate code for probing the stub cache table. |
// Arguments extra, extra2 and extra3 may be used to pass additional scratch |
// registers. Set to no_reg if not needed. |
@@ -128,25 +78,21 @@ class StubCache { |
kSecondary |
}; |
- |
SCTableReference key_reference(StubCache::Table table) { |
return SCTableReference( |
reinterpret_cast<Address>(&first_entry(table)->key)); |
} |
- |
SCTableReference map_reference(StubCache::Table table) { |
return SCTableReference( |
reinterpret_cast<Address>(&first_entry(table)->map)); |
} |
- |
SCTableReference value_reference(StubCache::Table table) { |
return SCTableReference( |
reinterpret_cast<Address>(&first_entry(table)->value)); |
} |
- |
StubCache::Entry* first_entry(StubCache::Table table) { |
switch (table) { |
case StubCache::kPrimary: return StubCache::primary_; |
@@ -157,18 +103,6 @@ class StubCache { |
} |
Isolate* isolate() { return isolate_; } |
- Heap* heap() { return isolate()->heap(); } |
- Factory* factory() { return isolate()->factory(); } |
- |
- // These constants describe the structure of the interceptor arguments on the |
- // stack. The arguments are pushed by the (platform-specific) |
- // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and |
- // LoadWithInterceptor. |
- static const int kInterceptorArgsNameIndex = 0; |
- static const int kInterceptorArgsInfoIndex = 1; |
- static const int kInterceptorArgsThisIndex = 2; |
- static const int kInterceptorArgsHolderIndex = 3; |
- static const int kInterceptorArgsLength = 4; |
// Setting the entry size such that the index is shifted by Name::kHashShift |
// is convenient; shifting down the length field (to extract the hash code) |
@@ -335,6 +269,42 @@ class PropertyAccessCompiler BASE_EMBEDDED { |
class PropertyICCompiler : public PropertyAccessCompiler { |
public: |
+ // Finds the Code object stored in the Heap::non_monomorphic_cache(). |
+ static Code* FindPreMonomorphicIC(Isolate* isolate, Code::Kind kind, |
+ ExtraICState extra_ic_state); |
+ |
+ // Named |
+ static Handle<Code> ComputeLoad(Isolate* isolate, InlineCacheState ic_state, |
+ ExtraICState extra_state); |
+ static Handle<Code> ComputeStore(Isolate* isolate, InlineCacheState ic_state, |
+ ExtraICState extra_state); |
+ |
+ static Handle<Code> ComputeMonomorphicIC(Code::Kind kind, Handle<Name> name, |
+ Handle<HeapType> type, |
+ Handle<Code> handler, |
+ ExtraICState extra_ic_state); |
+ static Handle<Code> ComputePolymorphicIC( |
+ Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers, |
+ int number_of_valid_maps, Handle<Name> name, ExtraICState extra_ic_state); |
+ |
+ // Keyed |
+ static Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map); |
+ |
+ static Handle<Code> ComputeKeyedStoreElement(Handle<Map> receiver_map, |
+ StrictMode strict_mode, |
+ KeyedAccessStoreMode store_mode); |
+ static Handle<Code> ComputeLoadElementPolymorphic( |
+ MapHandleList* receiver_maps); |
+ static Handle<Code> ComputeStoreElementPolymorphic( |
+ MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode, |
+ StrictMode strict_mode); |
+ |
+ // Compare nil |
+ static Handle<Code> ComputeCompareNil(Handle<Map> receiver_map, |
+ CompareNilICStub* stub); |
+ |
+ |
+ private: |
PropertyICCompiler(Isolate* isolate, Code::Kind kind, |
ExtraICState extra_ic_state = kNoExtraICState, |
CacheHolderFlag cache_holder = kCacheOnReceiver) |
@@ -356,7 +326,6 @@ class PropertyICCompiler : public PropertyAccessCompiler { |
Handle<Code> CompileMonomorphic(Handle<HeapType> type, Handle<Code> handler, |
Handle<Name> name, IcCheckType check); |
- |
Handle<Code> CompilePolymorphic(TypeHandleList* types, |
CodeHandleList* handlers, Handle<Name> name, |
Code::StubType type, IcCheckType check); |
@@ -365,8 +334,10 @@ class PropertyICCompiler : public PropertyAccessCompiler { |
KeyedAccessStoreMode store_mode); |
Handle<Code> CompileIndexedStorePolymorphic(MapHandleList* receiver_maps, |
KeyedAccessStoreMode store_mode); |
+ Handle<Code> CompileIndexedStorePolymorphic(MapHandleList* receiver_maps, |
+ CodeHandleList* handler_stubs, |
+ MapHandleList* transitioned_maps); |
- private: |
bool IncludesNumberType(TypeHandleList* types); |
Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name, |
@@ -391,9 +362,6 @@ class PropertyICCompiler : public PropertyAccessCompiler { |
} |
} |
- Handle<Code> CompileIndexedStorePolymorphic(MapHandleList* receiver_maps, |
- CodeHandleList* handler_stubs, |
- MapHandleList* transitioned_maps); |
const ExtraICState extra_ic_state_; |
}; |
@@ -514,9 +482,8 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler { |
Handle<Name> name, |
Handle<JSFunction> getter); |
- Handle<Code> CompileLoadNonexistent(Handle<HeapType> type, |
- Handle<JSObject> last, |
- Handle<Name> name); |
+ static Handle<Code> ComputeLoadNonexistent(Handle<Name> name, |
+ Handle<HeapType> type); |
Handle<Code> CompileLoadGlobal(Handle<HeapType> type, |
Handle<GlobalObject> holder, |
@@ -539,6 +506,16 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler { |
Register scratch2, |
Label* miss_label); |
+ // These constants describe the structure of the interceptor arguments on the |
+ // stack. The arguments are pushed by the (platform-specific) |
+ // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and |
+ // LoadWithInterceptor. |
+ static const int kInterceptorArgsNameIndex = 0; |
+ static const int kInterceptorArgsInfoIndex = 1; |
+ static const int kInterceptorArgsThisIndex = 2; |
+ static const int kInterceptorArgsHolderIndex = 3; |
+ static const int kInterceptorArgsLength = 4; |
+ |
protected: |
virtual Register FrontendHeader(Handle<HeapType> type, Register object_reg, |
Handle<JSObject> holder, Handle<Name> name, |
@@ -550,6 +527,8 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler { |
Register CallbackFrontend(Handle<HeapType> type, Register object_reg, |
Handle<JSObject> holder, Handle<Name> name, |
Handle<Object> callback); |
+ Handle<Code> CompileLoadNonexistent(Handle<HeapType> type, |
+ Handle<JSObject> last, Handle<Name> name); |
void NonexistentFrontend(Handle<HeapType> type, Handle<JSObject> last, |
Handle<Name> name); |