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 Node* JSGraph::AllocateInNewSpaceStubConstant() {
     18   return CACHED(kAllocateInNewSpaceStubConstant,
     19                 HeapConstant(isolate()->builtins()->AllocateInNewSpace()));
     20 }
     21 
     22 Node* JSGraph::AllocateInOldSpaceStubConstant() {
     23   return CACHED(kAllocateInOldSpaceStubConstant,
     24                 HeapConstant(isolate()->builtins()->AllocateInOldSpace()));
     25 }
     26 
     27 Node* JSGraph::ToNumberBuiltinConstant() {
     28   return CACHED(kToNumberBuiltinConstant,
     29                 HeapConstant(isolate()->builtins()->ToNumber()));
     30 }
     31 
     32 Node* JSGraph::CEntryStubConstant(int result_size) {
     33   if (result_size == 1) {
     34     return CACHED(kCEntryStubConstant,
     35                   HeapConstant(CEntryStub(isolate(), 1).GetCode()));
     36   }
     37   return HeapConstant(CEntryStub(isolate(), result_size).GetCode());
     38 }
     39 
     40 
     41 Node* JSGraph::EmptyFixedArrayConstant() {
     42   return CACHED(kEmptyFixedArrayConstant,
     43                 HeapConstant(factory()->empty_fixed_array()));
     44 }
     45 
     46 Node* JSGraph::EmptyLiteralsArrayConstant() {
     47   return CACHED(kEmptyLiteralsArrayConstant,
     48                 HeapConstant(factory()->empty_literals_array()));
     49 }
     50 
     51 Node* JSGraph::HeapNumberMapConstant() {
     52   return CACHED(kHeapNumberMapConstant,
     53                 HeapConstant(factory()->heap_number_map()));
     54 }
     55 
     56 Node* JSGraph::OptimizedOutConstant() {
     57   return CACHED(kOptimizedOutConstant,
     58                 HeapConstant(factory()->optimized_out()));
     59 }
     60 
     61 Node* JSGraph::StaleRegisterConstant() {
     62   return CACHED(kStaleRegisterConstant,
     63                 HeapConstant(factory()->stale_register()));
     64 }
     65 
     66 Node* JSGraph::UndefinedConstant() {
     67   return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value()));
     68 }
     69 
     70 
     71 Node* JSGraph::TheHoleConstant() {
     72   return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value()));
     73 }
     74 
     75 
     76 Node* JSGraph::TrueConstant() {
     77   return CACHED(kTrueConstant, HeapConstant(factory()->true_value()));
     78 }
     79 
     80 
     81 Node* JSGraph::FalseConstant() {
     82   return CACHED(kFalseConstant, HeapConstant(factory()->false_value()));
     83 }
     84 
     85 
     86 Node* JSGraph::NullConstant() {
     87   return CACHED(kNullConstant, HeapConstant(factory()->null_value()));
     88 }
     89 
     90 
     91 Node* JSGraph::ZeroConstant() {
     92   return CACHED(kZeroConstant, NumberConstant(0.0));
     93 }
     94 
     95 
     96 Node* JSGraph::OneConstant() {
     97   return CACHED(kOneConstant, NumberConstant(1.0));
     98 }
     99 
    100 
    101 Node* JSGraph::NaNConstant() {
    102   return CACHED(kNaNConstant,
    103                 NumberConstant(std::numeric_limits<double>::quiet_NaN()));
    104 }
    105 
    106 
    107 Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
    108   Node** loc = cache_.FindHeapConstant(value);
    109   if (*loc == nullptr) {
    110     *loc = graph()->NewNode(common()->HeapConstant(value));
    111   }
    112   return *loc;
    113 }
    114 
    115 
    116 Node* JSGraph::Constant(Handle<Object> value) {
    117   // Dereference the handle to determine if a number constant or other
    118   // canonicalized node can be used.
    119   if (value->IsNumber()) {
    120     return Constant(value->Number());
    121   } else if (value->IsUndefined(isolate())) {
    122     return UndefinedConstant();
    123   } else if (value->IsTrue(isolate())) {
    124     return TrueConstant();
    125   } else if (value->IsFalse(isolate())) {
    126     return FalseConstant();
    127   } else if (value->IsNull(isolate())) {
    128     return NullConstant();
    129   } else if (value->IsTheHole(isolate())) {
    130     return TheHoleConstant();
    131   } else {
    132     return HeapConstant(Handle<HeapObject>::cast(value));
    133   }
    134 }
    135 
    136 
    137 Node* JSGraph::Constant(double value) {
    138   if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
    139   if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
    140   return NumberConstant(value);
    141 }
    142 
    143 
    144 Node* JSGraph::Constant(int32_t value) {
    145   if (value == 0) return ZeroConstant();
    146   if (value == 1) return OneConstant();
    147   return NumberConstant(value);
    148 }
    149 
    150 
    151 Node* JSGraph::Int32Constant(int32_t value) {
    152   Node** loc = cache_.FindInt32Constant(value);
    153   if (*loc == nullptr) {
    154     *loc = graph()->NewNode(common()->Int32Constant(value));
    155   }
    156   return *loc;
    157 }
    158 
    159 
    160 Node* JSGraph::Int64Constant(int64_t value) {
    161   Node** loc = cache_.FindInt64Constant(value);
    162   if (*loc == nullptr) {
    163     *loc = graph()->NewNode(common()->Int64Constant(value));
    164   }
    165   return *loc;
    166 }
    167 
    168 Node* JSGraph::RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
    169   Node** loc = cache_.FindRelocatableInt32Constant(
    170       value, static_cast<RelocInfoMode>(rmode));
    171   if (*loc == nullptr) {
    172     *loc = graph()->NewNode(common()->RelocatableInt32Constant(value, rmode));
    173   }
    174   return *loc;
    175 }
    176 
    177 Node* JSGraph::RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
    178   Node** loc = cache_.FindRelocatableInt64Constant(
    179       value, static_cast<RelocInfoMode>(rmode));
    180   if (*loc == nullptr) {
    181     *loc = graph()->NewNode(common()->RelocatableInt64Constant(value, rmode));
    182   }
    183   return *loc;
    184 }
    185 
    186 Node* JSGraph::RelocatableIntPtrConstant(intptr_t value,
    187                                          RelocInfo::Mode rmode) {
    188   return kPointerSize == 8
    189              ? RelocatableInt64Constant(value, rmode)
    190              : RelocatableInt32Constant(static_cast<int>(value), rmode);
    191 }
    192 
    193 Node* JSGraph::NumberConstant(double value) {
    194   Node** loc = cache_.FindNumberConstant(value);
    195   if (*loc == nullptr) {
    196     *loc = graph()->NewNode(common()->NumberConstant(value));
    197   }
    198   return *loc;
    199 }
    200 
    201 
    202 Node* JSGraph::Float32Constant(float value) {
    203   Node** loc = cache_.FindFloat32Constant(value);
    204   if (*loc == nullptr) {
    205     *loc = graph()->NewNode(common()->Float32Constant(value));
    206   }
    207   return *loc;
    208 }
    209 
    210 
    211 Node* JSGraph::Float64Constant(double value) {
    212   Node** loc = cache_.FindFloat64Constant(value);
    213   if (*loc == nullptr) {
    214     *loc = graph()->NewNode(common()->Float64Constant(value));
    215   }
    216   return *loc;
    217 }
    218 
    219 
    220 Node* JSGraph::ExternalConstant(ExternalReference reference) {
    221   Node** loc = cache_.FindExternalConstant(reference);
    222   if (*loc == nullptr) {
    223     *loc = graph()->NewNode(common()->ExternalConstant(reference));
    224   }
    225   return *loc;
    226 }
    227 
    228 
    229 Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) {
    230   return ExternalConstant(ExternalReference(function_id, isolate()));
    231 }
    232 
    233 Node* JSGraph::EmptyStateValues() {
    234   return CACHED(kEmptyStateValues, graph()->NewNode(common()->StateValues(0)));
    235 }
    236 
    237 Node* JSGraph::Dead() {
    238   return CACHED(kDead, graph()->NewNode(common()->Dead()));
    239 }
    240 
    241 
    242 void JSGraph::GetCachedNodes(NodeVector* nodes) {
    243   cache_.GetCachedNodes(nodes);
    244   for (size_t i = 0; i < arraysize(cached_nodes_); i++) {
    245     if (Node* node = cached_nodes_[i]) {
    246       if (!node->IsDead()) nodes->push_back(node);
    247     }
    248   }
    249 }
    250 
    251 }  // namespace compiler
    252 }  // namespace internal
    253 }  // namespace v8
    254