OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ast.h" | 5 #include "src/ast.h" |
6 | 6 |
7 #include <cmath> // For isfinite. | 7 #include <cmath> // For isfinite. |
8 #include "src/builtins.h" | 8 #include "src/builtins.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/contexts.h" | 10 #include "src/contexts.h" |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 if (shared->start_position() == start_position()) { | 174 if (shared->start_position() == start_position()) { |
175 shared_info_ = Handle<SharedFunctionInfo>(shared); | 175 shared_info_ = Handle<SharedFunctionInfo>(shared); |
176 break; | 176 break; |
177 } | 177 } |
178 } | 178 } |
179 } | 179 } |
180 } | 180 } |
181 | 181 |
182 | 182 |
183 ObjectLiteralProperty::ObjectLiteralProperty( | 183 ObjectLiteralProperty::ObjectLiteralProperty( |
184 Zone* zone, Literal* key, Expression* value) { | 184 Zone* zone, Expression* key, Expression* value, bool is_computed_name) { |
185 emit_store_ = true; | 185 emit_store_ = true; |
186 key_ = key; | 186 key_ = key; |
187 value_ = value; | 187 value_ = value; |
188 Handle<Object> k = key->value(); | 188 if (is_computed_name) { |
189 if (k->IsInternalizedString() && | 189 kind_ = COMPUTED_NAME; |
190 String::Equals(Handle<String>::cast(k), | |
191 zone->isolate()->factory()->proto_string())) { | |
192 kind_ = PROTOTYPE; | |
193 } else if (value_->AsMaterializedLiteral() != NULL) { | |
194 kind_ = MATERIALIZED_LITERAL; | |
195 } else if (value_->IsLiteral()) { | |
196 kind_ = CONSTANT; | |
197 } else { | 190 } else { |
198 kind_ = COMPUTED; | 191 Handle<Object> k = key->AsLiteral()->value(); |
| 192 if (k->IsInternalizedString() && |
| 193 String::Equals(Handle<String>::cast(k), |
| 194 zone->isolate()->factory()->proto_string())) { |
| 195 kind_ = PROTOTYPE; |
| 196 } else if (value_->AsMaterializedLiteral() != NULL) { |
| 197 kind_ = MATERIALIZED_LITERAL; |
| 198 } else if (value_->IsLiteral()) { |
| 199 kind_ = CONSTANT; |
| 200 } else { |
| 201 kind_ = COMPUTED; |
| 202 } |
199 } | 203 } |
200 } | 204 } |
201 | 205 |
202 | 206 |
203 ObjectLiteralProperty::ObjectLiteralProperty( | 207 ObjectLiteralProperty::ObjectLiteralProperty( |
204 Zone* zone, bool is_getter, FunctionLiteral* value) { | 208 Zone* zone, bool is_getter, FunctionLiteral* value) { |
205 emit_store_ = true; | 209 emit_store_ = true; |
206 value_ = value; | 210 value_ = value; |
207 kind_ = is_getter ? GETTER : SETTER; | 211 kind_ = is_getter ? GETTER : SETTER; |
208 } | 212 } |
(...skipping 16 matching lines...) Expand all Loading... |
225 } | 229 } |
226 | 230 |
227 | 231 |
228 void ObjectLiteral::CalculateEmitStore(Zone* zone) { | 232 void ObjectLiteral::CalculateEmitStore(Zone* zone) { |
229 ZoneAllocationPolicy allocator(zone); | 233 ZoneAllocationPolicy allocator(zone); |
230 | 234 |
231 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, | 235 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, |
232 allocator); | 236 allocator); |
233 for (int i = properties()->length() - 1; i >= 0; i--) { | 237 for (int i = properties()->length() - 1; i >= 0; i--) { |
234 ObjectLiteral::Property* property = properties()->at(i); | 238 ObjectLiteral::Property* property = properties()->at(i); |
235 Literal* literal = property->key(); | 239 if (property->kind() == ObjectLiteral::Property::COMPUTED_NAME) continue; |
| 240 Literal* literal = property->key()->AsLiteral(); |
236 if (literal->value()->IsNull()) continue; | 241 if (literal->value()->IsNull()) continue; |
237 uint32_t hash = literal->Hash(); | 242 uint32_t hash = literal->Hash(); |
238 // If the key of a computed property is in the table, do not emit | 243 // If the key of a computed property is in the table, do not emit |
239 // a store for the property later. | 244 // a store for the property later. |
240 if ((property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL || | 245 if ((property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL || |
241 property->kind() == ObjectLiteral::Property::COMPUTED) && | 246 property->kind() == ObjectLiteral::Property::COMPUTED) && |
242 table.Lookup(literal, hash, false, allocator) != NULL) { | 247 table.Lookup(literal, hash, false, allocator) != NULL) { |
243 property->set_emit_store(false); | 248 property->set_emit_store(false); |
244 } else { | 249 } else { |
245 // Add key to the table. | 250 // Add key to the table. |
(...skipping 21 matching lines...) Expand all Loading... |
267 bool is_simple = true; | 272 bool is_simple = true; |
268 int depth_acc = 1; | 273 int depth_acc = 1; |
269 uint32_t max_element_index = 0; | 274 uint32_t max_element_index = 0; |
270 uint32_t elements = 0; | 275 uint32_t elements = 0; |
271 for (int i = 0; i < properties()->length(); i++) { | 276 for (int i = 0; i < properties()->length(); i++) { |
272 ObjectLiteral::Property* property = properties()->at(i); | 277 ObjectLiteral::Property* property = properties()->at(i); |
273 if (!IsBoilerplateProperty(property)) { | 278 if (!IsBoilerplateProperty(property)) { |
274 is_simple = false; | 279 is_simple = false; |
275 continue; | 280 continue; |
276 } | 281 } |
| 282 |
| 283 if (position == boilerplate_properties_ * 2) { |
| 284 // Constant properties stop at the first computed name. |
| 285 ASSERT(property->kind() == ObjectLiteral::Property::COMPUTED_NAME); |
| 286 break; |
| 287 } |
| 288 ASSERT(property->kind() != ObjectLiteral::Property::COMPUTED_NAME); |
| 289 |
277 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); | 290 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); |
278 if (m_literal != NULL) { | 291 if (m_literal != NULL) { |
279 m_literal->BuildConstants(isolate); | 292 m_literal->BuildConstants(isolate); |
280 if (m_literal->depth() >= depth_acc) depth_acc = m_literal->depth() + 1; | 293 if (m_literal->depth() >= depth_acc) depth_acc = m_literal->depth() + 1; |
281 } | 294 } |
282 | 295 |
283 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined | 296 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined |
284 // value for COMPUTED properties, the real value is filled in at | 297 // value for COMPUTED properties, the real value is filled in at |
285 // runtime. The enumeration order is maintained. | 298 // runtime. The enumeration order is maintained. |
286 Handle<Object> key = property->key()->value(); | 299 Handle<Object> key = property->key()->AsLiteral()->value(); |
287 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); | 300 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); |
288 | 301 |
289 // Ensure objects that may, at any point in time, contain fields with double | 302 // Ensure objects that may, at any point in time, contain fields with double |
290 // representation are always treated as nested objects. This is true for | 303 // representation are always treated as nested objects. This is true for |
291 // computed fields (value is undefined), and smi and double literals | 304 // computed fields (value is undefined), and smi and double literals |
292 // (value->IsNumber()). | 305 // (value->IsNumber()). |
293 // TODO(verwaest): Remove once we can store them inline. | 306 // TODO(verwaest): Remove once we can store them inline. |
294 if (FLAG_track_double_fields && | 307 if (FLAG_track_double_fields && |
295 (value->IsNumber() || value->IsUninitialized())) { | 308 (value->IsNumber() || value->IsUninitialized())) { |
296 may_store_doubles_ = true; | 309 may_store_doubles_ = true; |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 if (is_monomorphic_) { | 638 if (is_monomorphic_) { |
626 target_ = oracle->GetCallNewTarget(CallNewFeedbackSlot()); | 639 target_ = oracle->GetCallNewTarget(CallNewFeedbackSlot()); |
627 if (!allocation_site_.is_null()) { | 640 if (!allocation_site_.is_null()) { |
628 elements_kind_ = allocation_site_->GetElementsKind(); | 641 elements_kind_ = allocation_site_->GetElementsKind(); |
629 } | 642 } |
630 } | 643 } |
631 } | 644 } |
632 | 645 |
633 | 646 |
634 void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { | 647 void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
635 TypeFeedbackId id = key()->LiteralFeedbackId(); | 648 ASSERT(key()->IsLiteral()); |
| 649 TypeFeedbackId id = key()->AsLiteral()->LiteralFeedbackId(); |
636 SmallMapList maps; | 650 SmallMapList maps; |
637 oracle->CollectReceiverTypes(id, &maps); | 651 oracle->CollectReceiverTypes(id, &maps); |
638 receiver_type_ = maps.length() == 1 ? maps.at(0) | 652 receiver_type_ = maps.length() == 1 ? maps.at(0) |
639 : Handle<Map>::null(); | 653 : Handle<Map>::null(); |
640 } | 654 } |
641 | 655 |
642 | 656 |
643 // ---------------------------------------------------------------------------- | 657 // ---------------------------------------------------------------------------- |
644 // Implementation of AstVisitor | 658 // Implementation of AstVisitor |
645 | 659 |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 OS::SNPrintF(buffer, "%d", Smi::cast(*value_)->value()); | 1163 OS::SNPrintF(buffer, "%d", Smi::cast(*value_)->value()); |
1150 str = arr; | 1164 str = arr; |
1151 } else { | 1165 } else { |
1152 str = DoubleToCString(value_->Number(), buffer); | 1166 str = DoubleToCString(value_->Number(), buffer); |
1153 } | 1167 } |
1154 return isolate_->factory()->NewStringFromAsciiChecked(str); | 1168 return isolate_->factory()->NewStringFromAsciiChecked(str); |
1155 } | 1169 } |
1156 | 1170 |
1157 | 1171 |
1158 } } // namespace v8::internal | 1172 } } // namespace v8::internal |
OLD | NEW |