11cb0ef41Sopenharmony_ci// Copyright 2014 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h"
81cb0ef41Sopenharmony_ci#include "src/compiler/node-properties.h"
91cb0ef41Sopenharmony_ci#include "src/compiler/typer.h"
101cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace v8 {
131cb0ef41Sopenharmony_cinamespace internal {
141cb0ef41Sopenharmony_cinamespace compiler {
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci#define GET_CACHED_FIELD(ptr, expr) (*(ptr)) ? *(ptr) : (*(ptr) = (expr))
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci#define DEFINE_GETTER(name, expr) \
191cb0ef41Sopenharmony_ci  Node* JSGraph::name() { return GET_CACHED_FIELD(&name##_, expr); }
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciNode* JSGraph::CEntryStubConstant(int result_size, SaveFPRegsMode save_doubles,
221cb0ef41Sopenharmony_ci                                  ArgvMode argv_mode, bool builtin_exit_frame) {
231cb0ef41Sopenharmony_ci  if (save_doubles == SaveFPRegsMode::kIgnore &&
241cb0ef41Sopenharmony_ci      argv_mode == ArgvMode::kStack) {
251cb0ef41Sopenharmony_ci    DCHECK(result_size >= 1 && result_size <= 3);
261cb0ef41Sopenharmony_ci    if (!builtin_exit_frame) {
271cb0ef41Sopenharmony_ci      Node** ptr = nullptr;
281cb0ef41Sopenharmony_ci      if (result_size == 1) {
291cb0ef41Sopenharmony_ci        ptr = &CEntryStub1Constant_;
301cb0ef41Sopenharmony_ci      } else if (result_size == 2) {
311cb0ef41Sopenharmony_ci        ptr = &CEntryStub2Constant_;
321cb0ef41Sopenharmony_ci      } else {
331cb0ef41Sopenharmony_ci        DCHECK_EQ(3, result_size);
341cb0ef41Sopenharmony_ci        ptr = &CEntryStub3Constant_;
351cb0ef41Sopenharmony_ci      }
361cb0ef41Sopenharmony_ci      return GET_CACHED_FIELD(ptr, HeapConstant(CodeFactory::CEntry(
371cb0ef41Sopenharmony_ci                                       isolate(), result_size, save_doubles,
381cb0ef41Sopenharmony_ci                                       argv_mode, builtin_exit_frame)));
391cb0ef41Sopenharmony_ci    }
401cb0ef41Sopenharmony_ci    Node** ptr = builtin_exit_frame ? &CEntryStub1WithBuiltinExitFrameConstant_
411cb0ef41Sopenharmony_ci                                    : &CEntryStub1Constant_;
421cb0ef41Sopenharmony_ci    return GET_CACHED_FIELD(ptr, HeapConstant(CodeFactory::CEntry(
431cb0ef41Sopenharmony_ci                                     isolate(), result_size, save_doubles,
441cb0ef41Sopenharmony_ci                                     argv_mode, builtin_exit_frame)));
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci  return HeapConstant(CodeFactory::CEntry(isolate(), result_size, save_doubles,
471cb0ef41Sopenharmony_ci                                          argv_mode, builtin_exit_frame));
481cb0ef41Sopenharmony_ci}
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ciNode* JSGraph::Constant(const ObjectRef& ref) {
511cb0ef41Sopenharmony_ci  if (ref.IsSmi()) return Constant(ref.AsSmi());
521cb0ef41Sopenharmony_ci  if (ref.IsHeapNumber()) {
531cb0ef41Sopenharmony_ci    return Constant(ref.AsHeapNumber().value());
541cb0ef41Sopenharmony_ci  }
551cb0ef41Sopenharmony_ci  OddballType oddball_type =
561cb0ef41Sopenharmony_ci      ref.AsHeapObject().GetHeapObjectType().oddball_type();
571cb0ef41Sopenharmony_ci  if (oddball_type == OddballType::kUndefined) {
581cb0ef41Sopenharmony_ci    DCHECK(ref.object().equals(isolate()->factory()->undefined_value()));
591cb0ef41Sopenharmony_ci    return UndefinedConstant();
601cb0ef41Sopenharmony_ci  } else if (oddball_type == OddballType::kNull) {
611cb0ef41Sopenharmony_ci    DCHECK(ref.object().equals(isolate()->factory()->null_value()));
621cb0ef41Sopenharmony_ci    return NullConstant();
631cb0ef41Sopenharmony_ci  } else if (oddball_type == OddballType::kHole) {
641cb0ef41Sopenharmony_ci    DCHECK(ref.object().equals(isolate()->factory()->the_hole_value()));
651cb0ef41Sopenharmony_ci    return TheHoleConstant();
661cb0ef41Sopenharmony_ci  } else if (oddball_type == OddballType::kBoolean) {
671cb0ef41Sopenharmony_ci    if (ref.object().equals(isolate()->factory()->true_value())) {
681cb0ef41Sopenharmony_ci      return TrueConstant();
691cb0ef41Sopenharmony_ci    } else {
701cb0ef41Sopenharmony_ci      DCHECK(ref.object().equals(isolate()->factory()->false_value()));
711cb0ef41Sopenharmony_ci      return FalseConstant();
721cb0ef41Sopenharmony_ci    }
731cb0ef41Sopenharmony_ci  } else {
741cb0ef41Sopenharmony_ci    return HeapConstant(ref.AsHeapObject().object());
751cb0ef41Sopenharmony_ci  }
761cb0ef41Sopenharmony_ci}
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ciNode* JSGraph::Constant(double value) {
791cb0ef41Sopenharmony_ci  if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
801cb0ef41Sopenharmony_ci  if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
811cb0ef41Sopenharmony_ci  return NumberConstant(value);
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciNode* JSGraph::NumberConstant(double value) {
851cb0ef41Sopenharmony_ci  Node** loc = cache_.FindNumberConstant(value);
861cb0ef41Sopenharmony_ci  if (*loc == nullptr) {
871cb0ef41Sopenharmony_ci    *loc = graph()->NewNode(common()->NumberConstant(value));
881cb0ef41Sopenharmony_ci  }
891cb0ef41Sopenharmony_ci  return *loc;
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ciNode* JSGraph::HeapConstant(Handle<HeapObject> value) {
931cb0ef41Sopenharmony_ci  Node** loc = cache_.FindHeapConstant(value);
941cb0ef41Sopenharmony_ci  if (*loc == nullptr) {
951cb0ef41Sopenharmony_ci    *loc = graph()->NewNode(common()->HeapConstant(value));
961cb0ef41Sopenharmony_ci  }
971cb0ef41Sopenharmony_ci  return *loc;
981cb0ef41Sopenharmony_ci}
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_civoid JSGraph::GetCachedNodes(NodeVector* nodes) {
1011cb0ef41Sopenharmony_ci  cache_.GetCachedNodes(nodes);
1021cb0ef41Sopenharmony_ci#define DO_CACHED_FIELD(name) \
1031cb0ef41Sopenharmony_ci  if (name##_) nodes->push_back(name##_);
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  CACHED_GLOBAL_LIST(DO_CACHED_FIELD)
1061cb0ef41Sopenharmony_ci  CACHED_CENTRY_LIST(DO_CACHED_FIELD)
1071cb0ef41Sopenharmony_ci#undef DO_CACHED_FIELD
1081cb0ef41Sopenharmony_ci}
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ciDEFINE_GETTER(AllocateInYoungGenerationStubConstant,
1111cb0ef41Sopenharmony_ci              HeapConstant(BUILTIN_CODE(isolate(), AllocateInYoungGeneration)))
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciDEFINE_GETTER(AllocateRegularInYoungGenerationStubConstant,
1141cb0ef41Sopenharmony_ci              HeapConstant(BUILTIN_CODE(isolate(),
1151cb0ef41Sopenharmony_ci                                        AllocateRegularInYoungGeneration)))
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ciDEFINE_GETTER(AllocateInOldGenerationStubConstant,
1181cb0ef41Sopenharmony_ci              HeapConstant(BUILTIN_CODE(isolate(), AllocateInOldGeneration)))
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ciDEFINE_GETTER(AllocateRegularInOldGenerationStubConstant,
1211cb0ef41Sopenharmony_ci              HeapConstant(BUILTIN_CODE(isolate(),
1221cb0ef41Sopenharmony_ci                                        AllocateRegularInOldGeneration)))
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ciDEFINE_GETTER(ArrayConstructorStubConstant,
1251cb0ef41Sopenharmony_ci              HeapConstant(BUILTIN_CODE(isolate(), ArrayConstructorImpl)))
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ciDEFINE_GETTER(BigIntMapConstant, HeapConstant(factory()->bigint_map()))
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ciDEFINE_GETTER(BooleanMapConstant, HeapConstant(factory()->boolean_map()))
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ciDEFINE_GETTER(ToNumberBuiltinConstant,
1321cb0ef41Sopenharmony_ci              HeapConstant(BUILTIN_CODE(isolate(), ToNumber)))
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ciDEFINE_GETTER(PlainPrimitiveToNumberBuiltinConstant,
1351cb0ef41Sopenharmony_ci              HeapConstant(BUILTIN_CODE(isolate(), PlainPrimitiveToNumber)))
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ciDEFINE_GETTER(EmptyFixedArrayConstant,
1381cb0ef41Sopenharmony_ci              HeapConstant(factory()->empty_fixed_array()))
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ciDEFINE_GETTER(EmptyStringConstant, HeapConstant(factory()->empty_string()))
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ciDEFINE_GETTER(FixedArrayMapConstant, HeapConstant(factory()->fixed_array_map()))
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ciDEFINE_GETTER(PropertyArrayMapConstant,
1451cb0ef41Sopenharmony_ci              HeapConstant(factory()->property_array_map()))
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ciDEFINE_GETTER(FixedDoubleArrayMapConstant,
1481cb0ef41Sopenharmony_ci              HeapConstant(factory()->fixed_double_array_map()))
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ciDEFINE_GETTER(WeakFixedArrayMapConstant,
1511cb0ef41Sopenharmony_ci              HeapConstant(factory()->weak_fixed_array_map()))
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ciDEFINE_GETTER(HeapNumberMapConstant, HeapConstant(factory()->heap_number_map()))
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ciDEFINE_GETTER(OptimizedOutConstant, HeapConstant(factory()->optimized_out()))
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ciDEFINE_GETTER(StaleRegisterConstant, HeapConstant(factory()->stale_register()))
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ciDEFINE_GETTER(UndefinedConstant, HeapConstant(factory()->undefined_value()))
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ciDEFINE_GETTER(TheHoleConstant, HeapConstant(factory()->the_hole_value()))
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ciDEFINE_GETTER(TrueConstant, HeapConstant(factory()->true_value()))
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ciDEFINE_GETTER(FalseConstant, HeapConstant(factory()->false_value()))
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ciDEFINE_GETTER(NullConstant, HeapConstant(factory()->null_value()))
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ciDEFINE_GETTER(ZeroConstant, NumberConstant(0.0))
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ciDEFINE_GETTER(MinusZeroConstant, NumberConstant(-0.0))
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ciDEFINE_GETTER(OneConstant, NumberConstant(1.0))
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ciDEFINE_GETTER(MinusOneConstant, NumberConstant(-1.0))
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ciDEFINE_GETTER(NaNConstant,
1781cb0ef41Sopenharmony_ci              NumberConstant(std::numeric_limits<double>::quiet_NaN()))
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ciDEFINE_GETTER(EmptyStateValues,
1811cb0ef41Sopenharmony_ci              graph()->NewNode(common()->StateValues(0,
1821cb0ef41Sopenharmony_ci                                                     SparseInputMask::Dense())))
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ciDEFINE_GETTER(
1851cb0ef41Sopenharmony_ci    SingleDeadTypedStateValues,
1861cb0ef41Sopenharmony_ci    graph()->NewNode(common()->TypedStateValues(
1871cb0ef41Sopenharmony_ci        graph()->zone()->New<ZoneVector<MachineType>>(0, graph()->zone()),
1881cb0ef41Sopenharmony_ci        SparseInputMask(SparseInputMask::kEndMarker << 1))))
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci#undef DEFINE_GETTER
1911cb0ef41Sopenharmony_ci#undef GET_CACHED_FIELD
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci}  // namespace compiler
1941cb0ef41Sopenharmony_ci}  // namespace internal
1951cb0ef41Sopenharmony_ci}  // namespace v8
196