summaryrefslogtreecommitdiff
path: root/deps/v8/src/type-info.h
blob: 13a7f88b66095266fa6320ae5165664bd878575d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright 2012 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.

#ifndef V8_TYPE_INFO_H_
#define V8_TYPE_INFO_H_

#include "src/allocation.h"
#include "src/contexts.h"
#include "src/globals.h"
#include "src/parsing/token.h"
#include "src/types.h"
#include "src/zone.h"

namespace v8 {
namespace internal {

// Forward declarations.
class SmallMapList;


class TypeFeedbackOracle: public ZoneObject {
 public:
  TypeFeedbackOracle(Isolate* isolate, Zone* zone, Handle<Code> code,
                     Handle<TypeFeedbackVector> feedback_vector,
                     Handle<Context> native_context);

  InlineCacheState LoadInlineCacheState(FeedbackVectorSlot slot);
  bool StoreIsUninitialized(FeedbackVectorSlot slot);
  bool CallIsUninitialized(FeedbackVectorSlot slot);
  bool CallIsMonomorphic(FeedbackVectorSlot slot);
  bool CallNewIsMonomorphic(FeedbackVectorSlot slot);

  // TODO(1571) We can't use ForInStatement::ForInType as the return value due
  // to various cycles in our headers.
  // TODO(rossberg): once all oracle access is removed from ast.cc, it should
  // be possible.
  byte ForInType(FeedbackVectorSlot feedback_vector_slot);

  void GetStoreModeAndKeyType(FeedbackVectorSlot slot,
                              KeyedAccessStoreMode* store_mode,
                              IcCheckType* key_type);

  void PropertyReceiverTypes(FeedbackVectorSlot slot, Handle<Name> name,
                             SmallMapList* receiver_types);
  void KeyedPropertyReceiverTypes(FeedbackVectorSlot slot,
                                  SmallMapList* receiver_types, bool* is_string,
                                  IcCheckType* key_type);
  void AssignmentReceiverTypes(FeedbackVectorSlot slot, Handle<Name> name,
                               SmallMapList* receiver_types);
  void KeyedAssignmentReceiverTypes(FeedbackVectorSlot slot,
                                    SmallMapList* receiver_types,
                                    KeyedAccessStoreMode* store_mode,
                                    IcCheckType* key_type);
  void CountReceiverTypes(FeedbackVectorSlot slot,
                          SmallMapList* receiver_types);

  void CollectReceiverTypes(FeedbackVectorSlot slot, SmallMapList* types);
  template <class T>
  void CollectReceiverTypes(T* obj, SmallMapList* types);

  static bool IsRelevantFeedback(Map* map, Context* native_context) {
    Object* constructor = map->GetConstructor();
    return !constructor->IsJSFunction() ||
           JSFunction::cast(constructor)->context()->native_context() ==
               native_context;
  }

  Handle<JSFunction> GetCallTarget(FeedbackVectorSlot slot);
  Handle<AllocationSite> GetCallAllocationSite(FeedbackVectorSlot slot);
  Handle<JSFunction> GetCallNewTarget(FeedbackVectorSlot slot);
  Handle<AllocationSite> GetCallNewAllocationSite(FeedbackVectorSlot slot);

  // TODO(1571) We can't use ToBooleanStub::Types as the return value because
  // of various cycles in our headers. Death to tons of implementations in
  // headers!! :-P
  uint16_t ToBooleanTypes(TypeFeedbackId id);

  // Get type information for arithmetic operations and compares.
  void BinaryType(TypeFeedbackId id,
                  Type** left,
                  Type** right,
                  Type** result,
                  Maybe<int>* fixed_right_arg,
                  Handle<AllocationSite>* allocation_site,
                  Token::Value operation);

  void CompareType(TypeFeedbackId id,
                   Type** left,
                   Type** right,
                   Type** combined);

  Type* CountType(TypeFeedbackId id);

  Zone* zone() const { return zone_; }
  Isolate* isolate() const { return isolate_; }

 private:
  void CollectReceiverTypes(FeedbackVectorSlot slot, Handle<Name> name,
                            Code::Flags flags, SmallMapList* types);
  template <class T>
  void CollectReceiverTypes(T* obj, Handle<Name> name, Code::Flags flags,
                            SmallMapList* types);

  // Returns true if there is at least one string map and if
  // all maps are string maps.
  bool HasOnlyStringMaps(SmallMapList* receiver_types);

  void SetInfo(TypeFeedbackId id, Object* target);

  void BuildDictionary(Handle<Code> code);
  void GetRelocInfos(Handle<Code> code, ZoneList<RelocInfo>* infos);
  void CreateDictionary(Handle<Code> code, ZoneList<RelocInfo>* infos);
  void RelocateRelocInfos(ZoneList<RelocInfo>* infos,
                          Code* old_code,
                          Code* new_code);
  void ProcessRelocInfos(ZoneList<RelocInfo>* infos);

  // Returns an element from the backing store. Returns undefined if
  // there is no information.
  Handle<Object> GetInfo(TypeFeedbackId id);

  // Returns an element from the type feedback vector. Returns undefined
  // if there is no information.
  Handle<Object> GetInfo(FeedbackVectorSlot slot);

 private:
  Handle<Context> native_context_;
  Isolate* isolate_;
  Zone* zone_;
  Handle<UnseededNumberDictionary> dictionary_;
  Handle<TypeFeedbackVector> feedback_vector_;

  DISALLOW_COPY_AND_ASSIGN(TypeFeedbackOracle);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_TYPE_INFO_H_