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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 emit_store_ = emit_store; | 228 emit_store_ = emit_store; |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 bool ObjectLiteral::Property::emit_store() { | 232 bool ObjectLiteral::Property::emit_store() { |
233 return emit_store_; | 233 return emit_store_; |
234 } | 234 } |
235 | 235 |
236 | 236 |
237 void ObjectLiteral::CalculateEmitStore(Zone* zone) { | 237 void ObjectLiteral::CalculateEmitStore(Zone* zone) { |
| 238 const auto GETTER = ObjectLiteral::Property::GETTER; |
| 239 const auto SETTER = ObjectLiteral::Property::SETTER; |
| 240 |
238 ZoneAllocationPolicy allocator(zone); | 241 ZoneAllocationPolicy allocator(zone); |
239 | 242 |
240 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, | 243 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, |
241 allocator); | 244 allocator); |
242 for (int i = properties()->length() - 1; i >= 0; i--) { | 245 for (int i = properties()->length() - 1; i >= 0; i--) { |
243 ObjectLiteral::Property* property = properties()->at(i); | 246 ObjectLiteral::Property* property = properties()->at(i); |
244 if (property->is_computed_name()) continue; | 247 if (property->is_computed_name()) continue; |
| 248 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) continue; |
245 Literal* literal = property->key()->AsLiteral(); | 249 Literal* literal = property->key()->AsLiteral(); |
246 if (literal->value()->IsNull()) continue; | 250 DCHECK(!literal->value()->IsNull()); |
| 251 |
| 252 // If there is an existing entry do not emit a store unless the previous |
| 253 // entry was also an accessor. |
247 uint32_t hash = literal->Hash(); | 254 uint32_t hash = literal->Hash(); |
248 // If the key of a computed property value is in the table, do not emit | 255 ZoneHashMap::Entry* entry = table.Lookup(literal, hash, true, allocator); |
249 // a store for the property later. | 256 if (entry->value != NULL) { |
250 if ((property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL || | 257 auto previous_kind = |
251 property->kind() == ObjectLiteral::Property::COMPUTED) && | 258 static_cast<ObjectLiteral::Property*>(entry->value)->kind(); |
252 table.Lookup(literal, hash, false, allocator) != NULL) { | 259 if (!((property->kind() == GETTER && previous_kind == SETTER) || |
253 property->set_emit_store(false); | 260 (property->kind() == SETTER && previous_kind == GETTER))) { |
254 } else if (property->kind() != ObjectLiteral::Property::PROTOTYPE) { | 261 property->set_emit_store(false); |
255 // Add key to the table. | 262 } |
256 table.Lookup(literal, hash, true, allocator); | |
257 } | 263 } |
| 264 entry->value = property; |
258 } | 265 } |
259 } | 266 } |
260 | 267 |
261 | 268 |
262 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 269 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
263 return property != NULL && | 270 return property != NULL && |
264 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 271 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
265 } | 272 } |
266 | 273 |
267 | 274 |
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 // static | 1049 // static |
1043 bool Literal::Match(void* literal1, void* literal2) { | 1050 bool Literal::Match(void* literal1, void* literal2) { |
1044 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 1051 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
1045 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 1052 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
1046 return (x->IsString() && y->IsString() && *x->AsString() == *y->AsString()) || | 1053 return (x->IsString() && y->IsString() && *x->AsString() == *y->AsString()) || |
1047 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 1054 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
1048 } | 1055 } |
1049 | 1056 |
1050 | 1057 |
1051 } } // namespace v8::internal | 1058 } } // namespace v8::internal |
OLD | NEW |