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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 DCHECK_NOT_NULL(expr->AsFunctionLiteral()->scope()); | 220 DCHECK_NOT_NULL(expr->AsFunctionLiteral()->scope()); |
221 return expr->AsFunctionLiteral()->scope()->NeedsHomeObject(); | 221 return expr->AsFunctionLiteral()->scope()->NeedsHomeObject(); |
222 } | 222 } |
223 | 223 |
224 | 224 |
225 ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value, | 225 ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value, |
226 Kind kind, bool is_static, | 226 Kind kind, bool is_static, |
227 bool is_computed_name) | 227 bool is_computed_name) |
228 : key_(key), | 228 : key_(key), |
229 value_(value), | 229 value_(value), |
230 ic_slot_or_count_(FeedbackVectorICSlot::Invalid().ToInt()), | 230 slot_(FeedbackVectorICSlot::Invalid()), |
231 kind_(kind), | 231 kind_(kind), |
232 emit_store_(true), | 232 emit_store_(true), |
233 is_static_(is_static), | 233 is_static_(is_static), |
234 is_computed_name_(is_computed_name) {} | 234 is_computed_name_(is_computed_name) {} |
235 | 235 |
236 | 236 |
237 ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory, | 237 ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory, |
238 Expression* key, Expression* value, | 238 Expression* key, Expression* value, |
239 bool is_static, | 239 bool is_static, |
240 bool is_computed_name) | 240 bool is_computed_name) |
241 : key_(key), | 241 : key_(key), |
242 value_(value), | 242 value_(value), |
243 ic_slot_or_count_(FeedbackVectorICSlot::Invalid().ToInt()), | 243 slot_(FeedbackVectorICSlot::Invalid()), |
244 emit_store_(true), | 244 emit_store_(true), |
245 is_static_(is_static), | 245 is_static_(is_static), |
246 is_computed_name_(is_computed_name) { | 246 is_computed_name_(is_computed_name) { |
247 if (!is_computed_name && | 247 if (!is_computed_name && |
248 key->AsLiteral()->raw_value()->EqualsString( | 248 key->AsLiteral()->raw_value()->EqualsString( |
249 ast_value_factory->proto_string())) { | 249 ast_value_factory->proto_string())) { |
250 kind_ = PROTOTYPE; | 250 kind_ = PROTOTYPE; |
251 } else if (value_->AsMaterializedLiteral() != NULL) { | 251 } else if (value_->AsMaterializedLiteral() != NULL) { |
252 kind_ = MATERIALIZED_LITERAL; | 252 kind_ = MATERIALIZED_LITERAL; |
253 } else if (value_->IsLiteral()) { | 253 } else if (value_->IsLiteral()) { |
254 kind_ = CONSTANT; | 254 kind_ = CONSTANT; |
255 } else { | 255 } else { |
256 kind_ = COMPUTED; | 256 kind_ = COMPUTED; |
257 } | 257 } |
258 } | 258 } |
259 | 259 |
260 | 260 |
261 void ClassLiteral::AssignFeedbackVectorSlots(Isolate* isolate, | 261 void ClassLiteral::AssignFeedbackVectorSlots(Isolate* isolate, |
262 FeedbackVectorSpec* spec, | 262 FeedbackVectorSpec* spec, |
263 ICSlotCache* cache) { | 263 ICSlotCache* cache) { |
264 if (!FLAG_vector_stores) return; | 264 if (!FLAG_vector_stores) return; |
265 | 265 |
266 // This logic that computes the number of slots needed for vector store | 266 // This logic that computes the number of slots needed for vector store |
267 // ICs must mirror FullCodeGenerator::VisitClassLiteral. | 267 // ICs must mirror FullCodeGenerator::VisitClassLiteral. |
268 int ic_slots = 0; | |
269 if (NeedsProxySlot()) { | 268 if (NeedsProxySlot()) { |
270 ic_slots++; | 269 slot_ = spec->AddStoreICSlot(); |
271 } | 270 } |
272 | 271 |
273 for (int i = 0; i < properties()->length(); i++) { | 272 for (int i = 0; i < properties()->length(); i++) { |
274 ObjectLiteral::Property* property = properties()->at(i); | 273 ObjectLiteral::Property* property = properties()->at(i); |
275 // In case we don't end up using any slots. | |
276 property->set_ic_slot_count(0); | |
277 | |
278 Expression* value = property->value(); | 274 Expression* value = property->value(); |
279 if (FunctionLiteral::NeedsHomeObject(value)) { | 275 if (FunctionLiteral::NeedsHomeObject(value)) { |
280 property->set_ic_slot_count(1); | 276 property->set_slot(spec->AddStoreICSlot()); |
281 ic_slots++; | |
282 } | 277 } |
283 } | 278 } |
284 | |
285 if (ic_slots > 0) { | |
286 slot_ = spec->AddStoreICSlots(ic_slots); | |
287 } | |
288 } | 279 } |
289 | 280 |
290 | 281 |
291 void ClassLiteral::LayoutFeedbackSlots() { | |
292 int base_slot = slot_.ToInt(); | |
293 if (NeedsProxySlot()) base_slot++; | |
294 | |
295 for (int i = 0; i < properties()->length(); i++) { | |
296 ObjectLiteral::Property* property = properties()->at(i); | |
297 base_slot += property->set_base_slot(base_slot); | |
298 } | |
299 } | |
300 | |
301 | |
302 bool ObjectLiteral::Property::IsCompileTimeValue() { | 282 bool ObjectLiteral::Property::IsCompileTimeValue() { |
303 return kind_ == CONSTANT || | 283 return kind_ == CONSTANT || |
304 (kind_ == MATERIALIZED_LITERAL && | 284 (kind_ == MATERIALIZED_LITERAL && |
305 CompileTimeValue::IsCompileTimeValue(value_)); | 285 CompileTimeValue::IsCompileTimeValue(value_)); |
306 } | 286 } |
307 | 287 |
308 | 288 |
309 void ObjectLiteral::Property::set_emit_store(bool emit_store) { | 289 void ObjectLiteral::Property::set_emit_store(bool emit_store) { |
310 emit_store_ = emit_store; | 290 emit_store_ = emit_store; |
311 } | 291 } |
312 | 292 |
313 | 293 |
314 bool ObjectLiteral::Property::emit_store() { | 294 bool ObjectLiteral::Property::emit_store() { |
315 return emit_store_; | 295 return emit_store_; |
316 } | 296 } |
317 | 297 |
318 | 298 |
319 void ObjectLiteral::LayoutFeedbackSlots() { | |
320 int base_slot = slot_.ToInt(); | |
321 for (int i = 0; i < properties()->length(); i++) { | |
322 ObjectLiteral::Property* property = properties()->at(i); | |
323 base_slot += property->set_base_slot(base_slot); | |
324 } | |
325 } | |
326 | |
327 | |
328 void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate, | 299 void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate, |
329 FeedbackVectorSpec* spec, | 300 FeedbackVectorSpec* spec, |
330 ICSlotCache* cache) { | 301 ICSlotCache* cache) { |
331 if (!FLAG_vector_stores) return; | 302 if (!FLAG_vector_stores) return; |
332 | 303 |
333 // This logic that computes the number of slots needed for vector store | 304 // This logic that computes the number of slots needed for vector store |
334 // ics must mirror FullCodeGenerator::VisitObjectLiteral. | 305 // ics must mirror FullCodeGenerator::VisitObjectLiteral. |
335 int property_index = 0; | 306 int property_index = 0; |
336 for (; property_index < properties()->length(); property_index++) { | 307 for (; property_index < properties()->length(); property_index++) { |
337 ObjectLiteral::Property* property = properties()->at(property_index); | 308 ObjectLiteral::Property* property = properties()->at(property_index); |
338 // In case we don't end up using any slots. | |
339 property->set_ic_slot_count(0); | |
340 | |
341 if (property->is_computed_name()) break; | 309 if (property->is_computed_name()) break; |
342 if (property->IsCompileTimeValue()) continue; | 310 if (property->IsCompileTimeValue()) continue; |
343 | 311 |
344 Literal* key = property->key()->AsLiteral(); | 312 Literal* key = property->key()->AsLiteral(); |
345 Expression* value = property->value(); | 313 Expression* value = property->value(); |
346 switch (property->kind()) { | 314 switch (property->kind()) { |
347 case ObjectLiteral::Property::CONSTANT: | 315 case ObjectLiteral::Property::CONSTANT: |
348 UNREACHABLE(); | 316 UNREACHABLE(); |
349 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 317 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
350 // Fall through. | 318 // Fall through. |
351 case ObjectLiteral::Property::COMPUTED: | 319 case ObjectLiteral::Property::COMPUTED: |
352 // It is safe to use [[Put]] here because the boilerplate already | 320 // It is safe to use [[Put]] here because the boilerplate already |
353 // contains computed properties with an uninitialized value. | 321 // contains computed properties with an uninitialized value. |
354 if (key->value()->IsInternalizedString()) { | 322 if (key->value()->IsInternalizedString()) { |
355 if (property->emit_store()) { | 323 if (property->emit_store()) { |
356 int slot_count = 1; | 324 property->set_slot(spec->AddStoreICSlot()); |
357 if (FunctionLiteral::NeedsHomeObject(value)) { | 325 if (FunctionLiteral::NeedsHomeObject(value)) { |
358 slot_count++; | 326 spec->AddStoreICSlot(); |
359 } | 327 } |
360 property->set_ic_slot_count(slot_count); | |
361 } | 328 } |
362 break; | 329 break; |
363 } | 330 } |
364 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { | 331 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { |
365 property->set_ic_slot_count(1); | 332 property->set_slot(spec->AddStoreICSlot()); |
366 } | 333 } |
367 break; | 334 break; |
368 case ObjectLiteral::Property::PROTOTYPE: | 335 case ObjectLiteral::Property::PROTOTYPE: |
369 break; | 336 break; |
370 case ObjectLiteral::Property::GETTER: | 337 case ObjectLiteral::Property::GETTER: |
371 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { | 338 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { |
372 property->set_ic_slot_count(1); | 339 property->set_slot(spec->AddStoreICSlot()); |
373 } | 340 } |
374 break; | 341 break; |
375 case ObjectLiteral::Property::SETTER: | 342 case ObjectLiteral::Property::SETTER: |
376 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { | 343 if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) { |
377 property->set_ic_slot_count(1); | 344 property->set_slot(spec->AddStoreICSlot()); |
378 } | 345 } |
379 break; | 346 break; |
380 } | 347 } |
381 } | 348 } |
382 | 349 |
383 for (; property_index < properties()->length(); property_index++) { | 350 for (; property_index < properties()->length(); property_index++) { |
384 ObjectLiteral::Property* property = properties()->at(property_index); | 351 ObjectLiteral::Property* property = properties()->at(property_index); |
385 | 352 |
386 Expression* value = property->value(); | 353 Expression* value = property->value(); |
387 if (property->kind() != ObjectLiteral::Property::PROTOTYPE) { | 354 if (property->kind() != ObjectLiteral::Property::PROTOTYPE) { |
388 if (FunctionLiteral::NeedsHomeObject(value)) { | 355 if (FunctionLiteral::NeedsHomeObject(value)) { |
389 property->set_ic_slot_count(1); | 356 property->set_slot(spec->AddStoreICSlot()); |
390 } | 357 } |
391 } | 358 } |
392 } | 359 } |
393 | |
394 // How many slots did we allocate? | |
395 int ic_slots = 0; | |
396 for (int i = 0; i < properties()->length(); i++) { | |
397 ObjectLiteral::Property* property = properties()->at(i); | |
398 ic_slots += property->ic_slot_count(); | |
399 } | |
400 | |
401 if (ic_slots > 0) { | |
402 slot_ = spec->AddStoreICSlots(ic_slots); | |
403 } | |
404 } | 360 } |
405 | 361 |
406 | 362 |
407 void ObjectLiteral::CalculateEmitStore(Zone* zone) { | 363 void ObjectLiteral::CalculateEmitStore(Zone* zone) { |
408 const auto GETTER = ObjectLiteral::Property::GETTER; | 364 const auto GETTER = ObjectLiteral::Property::GETTER; |
409 const auto SETTER = ObjectLiteral::Property::SETTER; | 365 const auto SETTER = ObjectLiteral::Property::SETTER; |
410 | 366 |
411 ZoneAllocationPolicy allocator(zone); | 367 ZoneAllocationPolicy allocator(zone); |
412 | 368 |
413 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, | 369 ZoneHashMap table(Literal::Match, ZoneHashMap::kDefaultHashMapCapacity, |
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 bool Literal::Match(void* literal1, void* literal2) { | 1128 bool Literal::Match(void* literal1, void* literal2) { |
1173 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); | 1129 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); |
1174 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); | 1130 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); |
1175 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || | 1131 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || |
1176 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); | 1132 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); |
1177 } | 1133 } |
1178 | 1134 |
1179 | 1135 |
1180 } // namespace internal | 1136 } // namespace internal |
1181 } // namespace v8 | 1137 } // namespace v8 |
OLD | NEW |