Line data Source code
1 : // Copyright 2018 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/string-constants.h"
6 :
7 : #include "src/base/functional.h"
8 : #include "src/dtoa.h"
9 : #include "src/objects.h"
10 : #include "src/objects/string-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 10766 : Handle<String> StringConstantBase::AllocateStringConstant(
16 : Isolate* isolate) const {
17 10766 : if (!flattened_.is_null()) {
18 915 : return flattened_;
19 : }
20 :
21 : Handle<String> result;
22 9851 : switch (kind()) {
23 : case StringConstantKind::kStringLiteral: {
24 : result = static_cast<const StringLiteral*>(this)->str();
25 5601 : break;
26 : }
27 : case StringConstantKind::kNumberToStringConstant: {
28 : auto num_constant = static_cast<const NumberToStringConstant*>(this);
29 : Handle<Object> num_obj =
30 249 : isolate->factory()->NewNumber(num_constant->num());
31 249 : result = isolate->factory()->NumberToString(num_obj);
32 : break;
33 : }
34 : case StringConstantKind::kStringCons: {
35 : Handle<String> lhs =
36 : static_cast<const StringCons*>(this)->lhs()->AllocateStringConstant(
37 4001 : isolate);
38 : Handle<String> rhs =
39 : static_cast<const StringCons*>(this)->rhs()->AllocateStringConstant(
40 4001 : isolate);
41 8002 : result = isolate->factory()->NewConsString(lhs, rhs).ToHandleChecked();
42 : break;
43 : }
44 : }
45 :
46 : // TODO(mslekova): Normally we'd want to flatten the string here
47 : // but that results in OOM for too long strings.
48 : Memoize(result);
49 9851 : return flattened_;
50 : }
51 :
52 0 : bool StringConstantBase::operator==(const StringConstantBase& other) const {
53 0 : if (kind() != other.kind()) return false;
54 :
55 0 : switch (kind()) {
56 : case StringConstantKind::kStringLiteral: {
57 : return static_cast<const StringLiteral*>(this) ==
58 0 : static_cast<const StringLiteral*>(&other);
59 : }
60 : case StringConstantKind::kNumberToStringConstant: {
61 : return static_cast<const NumberToStringConstant*>(this) ==
62 0 : static_cast<const NumberToStringConstant*>(&other);
63 : }
64 : case StringConstantKind::kStringCons: {
65 : return static_cast<const StringCons*>(this) ==
66 0 : static_cast<const StringCons*>(&other);
67 : }
68 : }
69 0 : UNREACHABLE();
70 : }
71 :
72 0 : size_t hash_value(StringConstantBase const& base) {
73 0 : switch (base.kind()) {
74 : case StringConstantKind::kStringLiteral: {
75 0 : return hash_value(*static_cast<const StringLiteral*>(&base));
76 : }
77 : case StringConstantKind::kNumberToStringConstant: {
78 0 : return hash_value(*static_cast<const NumberToStringConstant*>(&base));
79 : }
80 : case StringConstantKind::kStringCons: {
81 0 : return hash_value(*static_cast<const StringCons*>(&base));
82 : }
83 : }
84 0 : UNREACHABLE();
85 : }
86 :
87 0 : bool operator==(StringLiteral const& lhs, StringLiteral const& rhs) {
88 0 : return lhs.str().address() == rhs.str().address();
89 : }
90 :
91 0 : bool operator!=(StringLiteral const& lhs, StringLiteral const& rhs) {
92 0 : return !(lhs == rhs);
93 : }
94 :
95 0 : size_t hash_value(StringLiteral const& p) {
96 0 : return base::hash_combine(p.str().address());
97 : }
98 :
99 0 : std::ostream& operator<<(std::ostream& os, StringLiteral const& p) {
100 0 : return os << Brief(*p.str());
101 : }
102 :
103 0 : bool operator==(NumberToStringConstant const& lhs,
104 : NumberToStringConstant const& rhs) {
105 0 : return lhs.num() == rhs.num();
106 : }
107 :
108 0 : bool operator!=(NumberToStringConstant const& lhs,
109 : NumberToStringConstant const& rhs) {
110 0 : return !(lhs == rhs);
111 : }
112 :
113 0 : size_t hash_value(NumberToStringConstant const& p) {
114 0 : return base::hash_combine(p.num());
115 : }
116 :
117 0 : std::ostream& operator<<(std::ostream& os, NumberToStringConstant const& p) {
118 0 : return os << p.num();
119 : }
120 :
121 0 : bool operator==(StringCons const& lhs, StringCons const& rhs) {
122 : // TODO(mslekova): Think if we can express this in a more readable manner
123 0 : return *(lhs.lhs()) == *(rhs.lhs()) && *(lhs.rhs()) == *(rhs.rhs());
124 : }
125 :
126 0 : bool operator!=(StringCons const& lhs, StringCons const& rhs) {
127 0 : return !(lhs == rhs);
128 : }
129 :
130 0 : size_t hash_value(StringCons const& p) {
131 0 : return base::hash_combine(*(p.lhs()), *(p.rhs()));
132 : }
133 :
134 0 : std::ostream& operator<<(std::ostream& os, const StringConstantBase* base) {
135 0 : os << "DelayedStringConstant: ";
136 0 : switch (base->kind()) {
137 : case StringConstantKind::kStringLiteral: {
138 0 : os << *static_cast<const StringLiteral*>(base);
139 0 : break;
140 : }
141 : case StringConstantKind::kNumberToStringConstant: {
142 : os << *static_cast<const NumberToStringConstant*>(base);
143 : break;
144 : }
145 : case StringConstantKind::kStringCons: {
146 0 : os << *static_cast<const StringCons*>(base);
147 0 : break;
148 : }
149 : }
150 0 : return os;
151 : }
152 :
153 0 : std::ostream& operator<<(std::ostream& os, StringCons const& p) {
154 0 : return os << p.lhs() << ", " << p.rhs();
155 : }
156 :
157 1956312 : size_t StringConstantBase::GetMaxStringConstantLength() const {
158 1956312 : switch (kind()) {
159 : case StringConstantKind::kStringLiteral: {
160 : return static_cast<const StringLiteral*>(this)
161 979940 : ->GetMaxStringConstantLength();
162 : }
163 : case StringConstantKind::kNumberToStringConstant: {
164 : return static_cast<const NumberToStringConstant*>(this)
165 : ->GetMaxStringConstantLength();
166 : }
167 : case StringConstantKind::kStringCons: {
168 976265 : return static_cast<const StringCons*>(this)->GetMaxStringConstantLength();
169 : }
170 : }
171 0 : UNREACHABLE();
172 : }
173 :
174 979940 : size_t StringLiteral::GetMaxStringConstantLength() const { return length_; }
175 :
176 0 : size_t NumberToStringConstant::GetMaxStringConstantLength() const {
177 0 : return kBase10MaximalLength + 1;
178 : }
179 :
180 976265 : size_t StringCons::GetMaxStringConstantLength() const {
181 976265 : return lhs()->GetMaxStringConstantLength() +
182 976265 : rhs()->GetMaxStringConstantLength();
183 : }
184 :
185 : } // namespace internal
186 122036 : } // namespace v8
|