Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/code-stubs.h"
      6 #include "src/compiler/js-graph.h"
      7 #include "src/compiler/node-properties.h"
      8 #include "src/compiler/typer.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 namespace compiler {
     13 
     14 #define CACHED(name, expr) \
     15   cached_nodes_[name] ? cached_nodes_[name] : (cached_nodes_[name] = (expr))
     16 
     17 
     18 Node* JSGraph::CEntryStubConstant(int result_size) {
     19   if (result_size == 1) {
     20     return CACHED(kCEntryStubConstant,
     21                   HeapConstant(CEntryStub(isolate(), 1).GetCode()));
     22   }
     23   return HeapConstant(CEntryStub(isolate(), result_size).GetCode());
     24 }
     25 
     26 
     27 Node* JSGraph::EmptyFixedArrayConstant() {
     28   return CACHED(kEmptyFixedArrayConstant,
     29                 HeapConstant(factory()->empty_fixed_array()));
     30 }
     31 
     32 
     33 Node* JSGraph::UndefinedConstant() {
     34   return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value()));
     35 }
     36 
     37 
     38 Node* JSGraph::TheHoleConstant() {
     39   return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value()));
     40 }
     41 
     42 
     43 Node* JSGraph::TrueConstant() {
     44   return CACHED(kTrueConstant, HeapConstant(factory()->true_value()));
     45 }
     46 
     47 
     48 Node* JSGraph::FalseConstant() {
     49   return CACHED(kFalseConstant, HeapConstant(factory()->false_value()));
     50 }
     51 
     52 
     53 Node* JSGraph::NullConstant() {
     54   return CACHED(kNullConstant, HeapConstant(factory()->null_value()));
     55 }
     56 
     57 
     58 Node* JSGraph::ZeroConstant() {
     59   return CACHED(kZeroConstant, NumberConstant(0.0));
     60 }
     61 
     62 
     63 Node* JSGraph::OneConstant() {
     64   return CACHED(kOneConstant, NumberConstant(1.0));
     65 }
     66 
     67 
     68 Node* JSGraph::NaNConstant() {
     69   return CACHED(kNaNConstant,
     70                 NumberConstant(std::numeric_limits<double>::quiet_NaN()));
     71 }
     72 
     73 
     74 Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
     75   if (value->IsConsString()) {
     76     value = String::Flatten(Handle<String>::cast(value), TENURED);
     77   }
     78   Node** loc = cache_.FindHeapConstant(value);
     79   if (*loc == nullptr) {
     80     *loc = graph()->NewNode(common()->HeapConstant(value));
     81   }
     82   return *loc;
     83 }
     84 
     85 
     86 Node* JSGraph::Constant(Handle<Object> value) {
     87   // Dereference the handle to determine if a number constant or other
     88   // canonicalized node can be used.
     89   if (value->IsNumber()) {
     90     return Constant(value->Number());
     91   } else if (value->IsUndefined()) {
     92     return UndefinedConstant();
     93   } else if (value->IsTrue()) {
     94     return TrueConstant();
     95   } else if (value->IsFalse()) {
     96     return FalseConstant();
     97   } else if (value->IsNull()) {
     98     return NullConstant();
     99   } else if (value->IsTheHole()) {
    100     return TheHoleConstant();
    101   } else {
    102     return HeapConstant(Handle<HeapObject>::cast(value));
    103   }
    104 }
    105 
    106 
    107 Node* JSGraph::Constant(double value) {
    108   if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
    109   if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
    110   return NumberConstant(value);
    111 }
    112 
    113 
    114 Node* JSGraph::Constant(int32_t value) {
    115   if (value == 0) return ZeroConstant();
    116   if (value == 1) return OneConstant();
    117   return NumberConstant(value);
    118 }
    119 
    120 
    121 Node* JSGraph::Int32Constant(int32_t value) {
    122   Node** loc = cache_.FindInt32Constant(value);
    123   if (*loc == nullptr) {
    124     *loc = graph()->NewNode(common()->Int32Constant(value));
    125   }
    126   return *loc;
    127 }
    128 
    129 
    130 Node* JSGraph::Int64Constant(int64_t value) {
    131   Node** loc = cache_.FindInt64Constant(value);
    132   if (*loc == nullptr) {
    133     *loc = graph()->NewNode(common()->Int64Constant(value));
    134   }
    135   return *loc;
    136 }
    137 
    138 
    139 Node* JSGraph::NumberConstant(double value) {
    140   Node** loc = cache_.FindNumberConstant(value);
    141   if (*loc == nullptr) {
    142     *loc = graph()->NewNode(common()->NumberConstant(value));
    143   }
    144   return *loc;
    145 }
    146 
    147 
    148 Node* JSGraph::Float32Constant(float value) {
    149   Node** loc = cache_.FindFloat32Constant(value);
    150   if (*loc == nullptr) {
    151     *loc = graph()->NewNode(common()->Float32Constant(value));
    152   }
    153   return *loc;
    154 }
    155 
    156 
    157 Node* JSGraph::Float64Constant(double value) {
    158   Node** loc = cache_.FindFloat64Constant(value);
    159   if (*loc == nullptr) {
    160     *loc = graph()->NewNode(common()->Float64Constant(value));
    161   }
    162   return *loc;
    163 }
    164 
    165 
    166 Node* JSGraph::ExternalConstant(ExternalReference reference) {
    167   Node** loc = cache_.FindExternalConstant(reference);
    168   if (*loc == nullptr) {
    169     *loc = graph()->NewNode(common()->ExternalConstant(reference));
    170   }
    171   return *loc;
    172 }
    173 
    174 
    175 Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) {
    176   return ExternalConstant(ExternalReference(function_id, isolate()));
    177 }
    178 
    179 
    180 Node* JSGraph::EmptyFrameState() {
    181   Node* empty_frame_state = cached_nodes_[kEmptyFrameState];
    182   if (!empty_frame_state || empty_frame_state->IsDead()) {
    183     Node* state_values = graph()->NewNode(common()->StateValues(0));
    184     empty_frame_state = graph()->NewNode(
    185         common()->FrameState(BailoutId::None(),
    186                              OutputFrameStateCombine::Ignore(), nullptr),
    187         state_values, state_values, state_values, NoContextConstant(),
    188         UndefinedConstant(), graph()->start());
    189     cached_nodes_[kEmptyFrameState] = empty_frame_state;
    190   }
    191   return empty_frame_state;
    192 }
    193 
    194 
    195 Node* JSGraph::Dead() {
    196   return CACHED(kDead, graph()->NewNode(common()->Dead()));
    197 }
    198 
    199 
    200 void JSGraph::GetCachedNodes(NodeVector* nodes) {
    201   cache_.GetCachedNodes(nodes);
    202   for (size_t i = 0; i < arraysize(cached_nodes_); i++) {
    203     if (Node* node = cached_nodes_[i]) {
    204       if (!node->IsDead()) nodes->push_back(node);
    205     }
    206   }
    207 }
    208 
    209 }  // namespace compiler
    210 }  // namespace internal
    211 }  // namespace v8
    212