11cb0ef41Sopenharmony_ci// Copyright 2015 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#ifndef V8_CODEGEN_SIGNATURE_H_ 61cb0ef41Sopenharmony_ci#define V8_CODEGEN_SIGNATURE_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/base/functional.h" 91cb0ef41Sopenharmony_ci#include "src/base/iterator.h" 101cb0ef41Sopenharmony_ci#include "src/codegen/machine-type.h" 111cb0ef41Sopenharmony_ci#include "src/zone/zone.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// Describes the inputs and outputs of a function or call. 171cb0ef41Sopenharmony_citemplate <typename T> 181cb0ef41Sopenharmony_ciclass Signature : public ZoneObject { 191cb0ef41Sopenharmony_ci public: 201cb0ef41Sopenharmony_ci constexpr Signature(size_t return_count, size_t parameter_count, 211cb0ef41Sopenharmony_ci const T* reps) 221cb0ef41Sopenharmony_ci : return_count_(return_count), 231cb0ef41Sopenharmony_ci parameter_count_(parameter_count), 241cb0ef41Sopenharmony_ci reps_(reps) { 251cb0ef41Sopenharmony_ci DCHECK_EQ(kReturnCountOffset, offsetof(Signature, return_count_)); 261cb0ef41Sopenharmony_ci DCHECK_EQ(kParameterCountOffset, offsetof(Signature, parameter_count_)); 271cb0ef41Sopenharmony_ci DCHECK_EQ(kRepsOffset, offsetof(Signature, reps_)); 281cb0ef41Sopenharmony_ci STATIC_ASSERT(std::is_standard_layout<Signature<T>>::value); 291cb0ef41Sopenharmony_ci } 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci size_t return_count() const { return return_count_; } 321cb0ef41Sopenharmony_ci size_t parameter_count() const { return parameter_count_; } 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci T GetParam(size_t index) const { 351cb0ef41Sopenharmony_ci DCHECK_LT(index, parameter_count_); 361cb0ef41Sopenharmony_ci return reps_[return_count_ + index]; 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci T GetReturn(size_t index = 0) const { 401cb0ef41Sopenharmony_ci DCHECK_LT(index, return_count_); 411cb0ef41Sopenharmony_ci return reps_[index]; 421cb0ef41Sopenharmony_ci } 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci // Iteration support. 451cb0ef41Sopenharmony_ci base::iterator_range<const T*> parameters() const { 461cb0ef41Sopenharmony_ci return {reps_ + return_count_, reps_ + return_count_ + parameter_count_}; 471cb0ef41Sopenharmony_ci } 481cb0ef41Sopenharmony_ci base::iterator_range<const T*> returns() const { 491cb0ef41Sopenharmony_ci return {reps_, reps_ + return_count_}; 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci base::iterator_range<const T*> all() const { 521cb0ef41Sopenharmony_ci return {reps_, reps_ + return_count_ + parameter_count_}; 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci bool operator==(const Signature& other) const { 561cb0ef41Sopenharmony_ci if (this == &other) return true; 571cb0ef41Sopenharmony_ci if (parameter_count() != other.parameter_count()) return false; 581cb0ef41Sopenharmony_ci if (return_count() != other.return_count()) return false; 591cb0ef41Sopenharmony_ci return std::equal(all().begin(), all().end(), other.all().begin()); 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci bool operator!=(const Signature& other) const { return !(*this == other); } 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci // For incrementally building signatures. 641cb0ef41Sopenharmony_ci class Builder { 651cb0ef41Sopenharmony_ci public: 661cb0ef41Sopenharmony_ci Builder(Zone* zone, size_t return_count, size_t parameter_count) 671cb0ef41Sopenharmony_ci : return_count_(return_count), 681cb0ef41Sopenharmony_ci parameter_count_(parameter_count), 691cb0ef41Sopenharmony_ci zone_(zone), 701cb0ef41Sopenharmony_ci rcursor_(0), 711cb0ef41Sopenharmony_ci pcursor_(0), 721cb0ef41Sopenharmony_ci buffer_(zone->NewArray<T>( 731cb0ef41Sopenharmony_ci static_cast<int>(return_count + parameter_count))) {} 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci const size_t return_count_; 761cb0ef41Sopenharmony_ci const size_t parameter_count_; 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci void AddReturn(T val) { 791cb0ef41Sopenharmony_ci DCHECK_LT(rcursor_, return_count_); 801cb0ef41Sopenharmony_ci buffer_[rcursor_++] = val; 811cb0ef41Sopenharmony_ci } 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci void AddParam(T val) { 841cb0ef41Sopenharmony_ci DCHECK_LT(pcursor_, parameter_count_); 851cb0ef41Sopenharmony_ci buffer_[return_count_ + pcursor_++] = val; 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci void AddParamAt(size_t index, T val) { 891cb0ef41Sopenharmony_ci DCHECK_LT(index, parameter_count_); 901cb0ef41Sopenharmony_ci buffer_[return_count_ + index] = val; 911cb0ef41Sopenharmony_ci pcursor_ = std::max(pcursor_, index + 1); 921cb0ef41Sopenharmony_ci } 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci Signature<T>* Build() { 951cb0ef41Sopenharmony_ci DCHECK_EQ(rcursor_, return_count_); 961cb0ef41Sopenharmony_ci DCHECK_EQ(pcursor_, parameter_count_); 971cb0ef41Sopenharmony_ci return zone_->New<Signature<T>>(return_count_, parameter_count_, buffer_); 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci private: 1011cb0ef41Sopenharmony_ci Zone* zone_; 1021cb0ef41Sopenharmony_ci size_t rcursor_; 1031cb0ef41Sopenharmony_ci size_t pcursor_; 1041cb0ef41Sopenharmony_ci T* buffer_; 1051cb0ef41Sopenharmony_ci }; 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci static Signature<T>* Build(Zone* zone, std::initializer_list<T> returns, 1081cb0ef41Sopenharmony_ci std::initializer_list<T> params) { 1091cb0ef41Sopenharmony_ci Builder builder(zone, returns.size(), params.size()); 1101cb0ef41Sopenharmony_ci for (T ret : returns) builder.AddReturn(ret); 1111cb0ef41Sopenharmony_ci for (T param : params) builder.AddParam(param); 1121cb0ef41Sopenharmony_ci return builder.Build(); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci static constexpr size_t kReturnCountOffset = 0; 1161cb0ef41Sopenharmony_ci static constexpr size_t kParameterCountOffset = 1171cb0ef41Sopenharmony_ci kReturnCountOffset + kSizetSize; 1181cb0ef41Sopenharmony_ci static constexpr size_t kRepsOffset = kParameterCountOffset + kSizetSize; 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci protected: 1211cb0ef41Sopenharmony_ci size_t return_count_; 1221cb0ef41Sopenharmony_ci size_t parameter_count_; 1231cb0ef41Sopenharmony_ci const T* reps_; 1241cb0ef41Sopenharmony_ci}; 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ciusing MachineSignature = Signature<MachineType>; 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_citemplate <typename T> 1291cb0ef41Sopenharmony_cisize_t hash_value(const Signature<T>& sig) { 1301cb0ef41Sopenharmony_ci // Hash over all contained representations, plus the parameter count to 1311cb0ef41Sopenharmony_ci // differentiate signatures with the same representation array but different 1321cb0ef41Sopenharmony_ci // parameter/return count. 1331cb0ef41Sopenharmony_ci size_t seed = base::hash_value(sig.parameter_count()); 1341cb0ef41Sopenharmony_ci for (T rep : sig.all()) seed = base::hash_combine(seed, base::hash<T>{}(rep)); 1351cb0ef41Sopenharmony_ci return seed; 1361cb0ef41Sopenharmony_ci} 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_citemplate <typename T, size_t kNumReturns = 0, size_t kNumParams = 0> 1391cb0ef41Sopenharmony_ciclass FixedSizeSignature : public Signature<T> { 1401cb0ef41Sopenharmony_ci public: 1411cb0ef41Sopenharmony_ci // Add return types to this signature (only allowed if there are none yet). 1421cb0ef41Sopenharmony_ci template <typename... ReturnTypes> 1431cb0ef41Sopenharmony_ci auto Returns(ReturnTypes... return_types) const { 1441cb0ef41Sopenharmony_ci static_assert(kNumReturns == 0, "Please specify all return types at once"); 1451cb0ef41Sopenharmony_ci return FixedSizeSignature<T, sizeof...(ReturnTypes), kNumParams>{ 1461cb0ef41Sopenharmony_ci std::initializer_list<T>{return_types...}.begin(), reps_}; 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci // Add parameters to this signature (only allowed if there are none yet). 1501cb0ef41Sopenharmony_ci template <typename... ParamTypes> 1511cb0ef41Sopenharmony_ci auto Params(ParamTypes... param_types) const { 1521cb0ef41Sopenharmony_ci static_assert(kNumParams == 0, "Please specify all parameters at once"); 1531cb0ef41Sopenharmony_ci return FixedSizeSignature<T, kNumReturns, sizeof...(ParamTypes)>{ 1541cb0ef41Sopenharmony_ci reps_, std::initializer_list<T>{param_types...}.begin()}; 1551cb0ef41Sopenharmony_ci } 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci private: 1581cb0ef41Sopenharmony_ci // Other template instantiations can call the private constructor. 1591cb0ef41Sopenharmony_ci template <typename T2, size_t kNumReturns2, size_t kNumParams2> 1601cb0ef41Sopenharmony_ci friend class FixedSizeSignature; 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ci FixedSizeSignature(const T* returns, const T* params) 1631cb0ef41Sopenharmony_ci : Signature<T>(kNumReturns, kNumParams, reps_) { 1641cb0ef41Sopenharmony_ci std::copy(returns, returns + kNumReturns, reps_); 1651cb0ef41Sopenharmony_ci std::copy(params, params + kNumParams, reps_ + kNumReturns); 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci T reps_[kNumReturns + kNumParams]; 1691cb0ef41Sopenharmony_ci}; 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci// Specialization for zero-sized signatures. 1721cb0ef41Sopenharmony_citemplate <typename T> 1731cb0ef41Sopenharmony_ciclass FixedSizeSignature<T, 0, 0> : public Signature<T> { 1741cb0ef41Sopenharmony_ci public: 1751cb0ef41Sopenharmony_ci constexpr FixedSizeSignature() : Signature<T>(0, 0, nullptr) {} 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci // Add return types. 1781cb0ef41Sopenharmony_ci template <typename... ReturnTypes> 1791cb0ef41Sopenharmony_ci static auto Returns(ReturnTypes... return_types) { 1801cb0ef41Sopenharmony_ci return FixedSizeSignature<T, sizeof...(ReturnTypes), 0>{ 1811cb0ef41Sopenharmony_ci std::initializer_list<T>{return_types...}.begin(), nullptr}; 1821cb0ef41Sopenharmony_ci } 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci // Add parameters. 1851cb0ef41Sopenharmony_ci template <typename... ParamTypes> 1861cb0ef41Sopenharmony_ci static auto Params(ParamTypes... param_types) { 1871cb0ef41Sopenharmony_ci return FixedSizeSignature<T, 0, sizeof...(ParamTypes)>{ 1881cb0ef41Sopenharmony_ci nullptr, std::initializer_list<T>{param_types...}.begin()}; 1891cb0ef41Sopenharmony_ci } 1901cb0ef41Sopenharmony_ci}; 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci} // namespace internal 1931cb0ef41Sopenharmony_ci} // namespace v8 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci#endif // V8_CODEGEN_SIGNATURE_H_ 196