summaryrefslogtreecommitdiffstats
path: root/src/type-info.h
blob: c8e35564ab69d5a116c0c60b28af6750f2bff596 (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
// 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/ast/ast-types.h"
#include "src/contexts.h"
#include "src/globals.h"
#include "src/parsing/token.h"
#include "src/zone/zone.h"

namespace v8 {
namespace internal {

// Forward declarations.
class SmallMapList;
class FeedbackNexus;
class StubCache;

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

  InlineCacheState LoadInlineCacheState(FeedbackSlot slot);
  bool StoreIsUninitialized(FeedbackSlot slot);
  bool CallIsUninitialized(FeedbackSlot slot);
  bool CallIsMonomorphic(FeedbackSlot slot);
  bool CallNewIsMonomorphic(FeedbackSlot 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(FeedbackSlot feedback_vector_slot);

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

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

  void CollectReceiverTypes(FeedbackSlot slot, SmallMapList* types);
  void CollectReceiverTypes(FeedbackNexus* nexus, 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(FeedbackSlot slot);
  Handle<AllocationSite> GetCallAllocationSite(FeedbackSlot slot);
  Handle<JSFunction> GetCallNewTarget(FeedbackSlot slot);
  Handle<AllocationSite> GetCallNewAllocationSite(FeedbackSlot slot);

  // TODO(1571) We can't use ToBooleanICStub::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, FeedbackSlot slot, AstType** left,
                  AstType** right, AstType** result,
                  Maybe<int>* fixed_right_arg,
                  Handle<AllocationSite>* allocation_site,
                  Token::Value operation);

  void CompareType(TypeFeedbackId id, FeedbackSlot slot, AstType** left,
                   AstType** right, AstType** combined);

  AstType* CountType(TypeFeedbackId id, FeedbackSlot slot);

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

 private:
  void CollectReceiverTypes(StubCache* stub_cache, FeedbackSlot slot,
                            Handle<Name> name, SmallMapList* types);
  void CollectReceiverTypes(StubCache* stub_cache, FeedbackNexus* nexus,
                            Handle<Name> name, 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(FeedbackSlot slot);

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

  DISALLOW_COPY_AND_ASSIGN(TypeFeedbackOracle);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_TYPE_INFO_H_