Index: src/ic/accessor-assembler.h |
diff --git a/src/ic/accessor-assembler.h b/src/ic/accessor-assembler.h |
index 3b75c2e54dc25d95b3e99151b529caeb13dc064d..3ce3d42edae1a945701b03be04a083a410845919 100644 |
--- a/src/ic/accessor-assembler.h |
+++ b/src/ic/accessor-assembler.h |
@@ -5,7 +5,7 @@ |
#ifndef V8_SRC_IC_ACCESSOR_ASSEMBLER_H_ |
#define V8_SRC_IC_ACCESSOR_ASSEMBLER_H_ |
-#include "src/globals.h" |
+#include "src/code-stub-assembler.h" |
namespace v8 { |
namespace internal { |
@@ -14,29 +14,179 @@ namespace compiler { |
class CodeAssemblerState; |
} |
-class AccessorAssembler { |
+class AccessorAssembler : public CodeStubAssembler { |
public: |
- static void GenerateLoadIC(compiler::CodeAssemblerState* state); |
- static void GenerateLoadICTrampoline(compiler::CodeAssemblerState* state); |
- static void GenerateLoadICProtoArray( |
- compiler::CodeAssemblerState* state, |
- bool throw_reference_error_if_nonexistent); |
- static void GenerateLoadGlobalIC(compiler::CodeAssemblerState* state, |
- TypeofMode typeof_mode); |
- static void GenerateLoadGlobalICTrampoline( |
- compiler::CodeAssemblerState* state, TypeofMode typeof_mode); |
- static void GenerateKeyedLoadICTF(compiler::CodeAssemblerState* state); |
- static void GenerateKeyedLoadICTrampolineTF( |
- compiler::CodeAssemblerState* state); |
- static void GenerateKeyedLoadICMegamorphic( |
- compiler::CodeAssemblerState* state); |
- static void GenerateLoadField(compiler::CodeAssemblerState* state); |
- static void GenerateStoreIC(compiler::CodeAssemblerState* state); |
- static void GenerateStoreICTrampoline(compiler::CodeAssemblerState* state); |
- static void GenerateKeyedStoreICTF(compiler::CodeAssemblerState* state, |
- LanguageMode language_mode); |
- static void GenerateKeyedStoreICTrampolineTF( |
- compiler::CodeAssemblerState* state, LanguageMode language_mode); |
+ typedef compiler::Node Node; |
+ |
+ explicit AccessorAssembler(compiler::CodeAssemblerState* state) |
+ : CodeStubAssembler(state) {} |
+ |
+ void GenerateLoadIC(); |
+ void GenerateLoadField(); |
+ void GenerateLoadICTrampoline(); |
+ void GenerateKeyedLoadIC(); |
+ void GenerateKeyedLoadICTrampoline(); |
+ void GenerateKeyedLoadIC_Megamorphic(); |
+ void GenerateStoreIC(); |
+ void GenerateStoreICTrampoline(); |
+ |
+ void GenerateLoadICProtoArray(bool throw_reference_error_if_nonexistent); |
+ |
+ void GenerateLoadGlobalIC(TypeofMode typeof_mode); |
+ void GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode); |
+ |
+ void GenerateKeyedStoreIC(LanguageMode language_mode); |
+ void GenerateKeyedStoreICTrampoline(LanguageMode language_mode); |
+ |
+ void TryProbeStubCache(StubCache* stub_cache, Node* receiver, Node* name, |
+ Label* if_handler, Variable* var_handler, |
+ Label* if_miss); |
+ |
+ Node* StubCachePrimaryOffsetForTesting(Node* name, Node* map) { |
+ return StubCachePrimaryOffset(name, map); |
+ } |
+ Node* StubCacheSecondaryOffsetForTesting(Node* name, Node* map) { |
+ return StubCacheSecondaryOffset(name, map); |
+ } |
+ |
+ protected: |
+ struct LoadICParameters { |
+ LoadICParameters(Node* context, Node* receiver, Node* name, Node* slot, |
+ Node* vector) |
+ : context(context), |
+ receiver(receiver), |
+ name(name), |
+ slot(slot), |
+ vector(vector) {} |
+ |
+ Node* context; |
+ Node* receiver; |
+ Node* name; |
+ Node* slot; |
+ Node* vector; |
+ }; |
+ |
+ struct StoreICParameters : public LoadICParameters { |
+ StoreICParameters(Node* context, Node* receiver, Node* name, Node* value, |
+ Node* slot, Node* vector) |
+ : LoadICParameters(context, receiver, name, slot, vector), |
+ value(value) {} |
+ Node* value; |
+ }; |
+ |
+ enum ElementSupport { kOnlyProperties, kSupportElements }; |
+ void HandleStoreICHandlerCase( |
+ const StoreICParameters* p, Node* handler, Label* miss, |
+ ElementSupport support_elements = kOnlyProperties); |
+ |
+ private: |
+ // Stub generation entry points. |
+ |
+ void LoadIC(const LoadICParameters* p); |
+ void LoadICProtoArray(const LoadICParameters* p, Node* handler, |
+ bool throw_reference_error_if_nonexistent); |
+ void LoadGlobalIC(const LoadICParameters* p, TypeofMode typeof_mode); |
+ void KeyedLoadIC(const LoadICParameters* p); |
+ void KeyedLoadICGeneric(const LoadICParameters* p); |
+ void StoreIC(const StoreICParameters* p); |
+ void KeyedStoreIC(const StoreICParameters* p, LanguageMode language_mode); |
+ |
+ // IC dispatcher behavior. |
+ |
+ // Checks monomorphic case. Returns {feedback} entry of the vector. |
+ Node* TryMonomorphicCase(Node* slot, Node* vector, Node* receiver_map, |
+ Label* if_handler, Variable* var_handler, |
+ Label* if_miss); |
+ void HandlePolymorphicCase(Node* receiver_map, Node* feedback, |
+ Label* if_handler, Variable* var_handler, |
+ Label* if_miss, int unroll_count); |
+ void HandleKeyedStorePolymorphicCase(Node* receiver_map, Node* feedback, |
+ Label* if_handler, Variable* var_handler, |
+ Label* if_transition_handler, |
+ Variable* var_transition_map_cell, |
+ Label* if_miss); |
+ |
+ // LoadIC implementation. |
+ |
+ void HandleLoadICHandlerCase( |
+ const LoadICParameters* p, Node* handler, Label* miss, |
+ ElementSupport support_elements = kOnlyProperties); |
+ |
+ void HandleLoadICSmiHandlerCase(const LoadICParameters* p, Node* holder, |
+ Node* smi_handler, Label* miss, |
+ ElementSupport support_elements); |
+ |
+ void HandleLoadICProtoHandlerCase(const LoadICParameters* p, Node* handler, |
+ Variable* var_holder, |
+ Variable* var_smi_handler, |
+ Label* if_smi_handler, Label* miss, |
+ bool throw_reference_error_if_nonexistent); |
+ |
+ Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler, |
+ Node* handler_length, Node* handler_flags, |
+ Label* miss, |
+ bool throw_reference_error_if_nonexistent); |
+ |
+ // LoadGlobalIC implementation. |
+ |
+ void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler, |
+ Label* miss, |
+ bool throw_reference_error_if_nonexistent); |
+ |
+ // StoreIC implementation. |
+ |
+ void HandleStoreICElementHandlerCase(const StoreICParameters* p, |
+ Node* handler, Label* miss); |
+ |
+ void HandleStoreICProtoHandler(const StoreICParameters* p, Node* handler, |
+ Label* miss); |
+ // If |transition| is nullptr then the normal field store is generated or |
+ // transitioning store otherwise. |
+ void HandleStoreICSmiHandlerCase(Node* handler_word, Node* holder, |
+ Node* value, Node* transition, Label* miss); |
+ // If |transition| is nullptr then the normal field store is generated or |
+ // transitioning store otherwise. |
+ void HandleStoreFieldAndReturn(Node* handler_word, Node* holder, |
+ Representation representation, Node* value, |
+ Node* transition, Label* miss); |
+ |
+ // Low-level helpers. |
+ |
+ Node* PrepareValueForStore(Node* handler_word, Node* holder, |
+ Representation representation, Node* transition, |
+ Node* value, Label* bailout); |
+ |
+ // Extends properties backing store by JSObject::kFieldsAdded elements. |
+ void ExtendPropertiesBackingStore(Node* object); |
+ |
+ void StoreNamedField(Node* handler_word, Node* object, bool is_inobject, |
+ Representation representation, Node* value, |
+ bool transition_to_field); |
+ |
+ void EmitFastElementsBoundsCheck(Node* object, Node* elements, |
+ Node* intptr_index, |
+ Node* is_jsarray_condition, Label* miss); |
+ void EmitElementLoad(Node* object, Node* elements, Node* elements_kind, |
+ Node* key, Node* is_jsarray_condition, Label* if_hole, |
+ Label* rebox_double, Variable* var_double_value, |
+ Label* unimplemented_elements_kind, Label* out_of_bounds, |
+ Label* miss); |
+ void CheckPrototype(Node* prototype_cell, Node* name, Label* miss); |
+ void NameDictionaryNegativeLookup(Node* object, Node* name, Label* miss); |
+ |
+ // Stub cache access helpers. |
+ |
+ // This enum is used here as a replacement for StubCache::Table to avoid |
+ // including stub cache header. |
+ enum StubCacheTable : int; |
+ |
+ Node* StubCachePrimaryOffset(Node* name, Node* map); |
+ Node* StubCacheSecondaryOffset(Node* name, Node* seed); |
+ |
+ void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id, |
+ Node* entry_offset, Node* name, Node* map, |
+ Label* if_handler, Variable* var_handler, |
+ Label* if_miss); |
}; |
} // namespace internal |