Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(864)

Side by Side Diff: src/hydrogen.cc

Issue 12114054: Supporting AllocationSiteInfo for Nested arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Now with ports to arm and x64 Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 5268 matching lines...) Expand 10 before | Expand all | Expand 10 after
5279 return false; 5279 return false;
5280 } 5280 }
5281 5281
5282 5282
5283 // Determines whether the given array or object literal boilerplate satisfies 5283 // Determines whether the given array or object literal boilerplate satisfies
5284 // all limits to be considered for fast deep-copying and computes the total 5284 // all limits to be considered for fast deep-copying and computes the total
5285 // size of all objects that are part of the graph. 5285 // size of all objects that are part of the graph.
5286 static bool IsFastLiteral(Handle<JSObject> boilerplate, 5286 static bool IsFastLiteral(Handle<JSObject> boilerplate,
5287 int max_depth, 5287 int max_depth,
5288 int* max_properties, 5288 int* max_properties,
5289 int* total_size) { 5289 int* total_size,
5290 bool allocation_sites_enabled) {
danno 2013/02/08 13:44:38 Maybe also pass this boolean flag around as a Allo
mvstanton 2013/02/11 11:11:24 Done. This area felt a little awkward because I ha
5290 ASSERT(max_depth >= 0 && *max_properties >= 0); 5291 ASSERT(max_depth >= 0 && *max_properties >= 0);
5291 if (max_depth == 0) return false; 5292 if (max_depth == 0) return false;
5292 5293
5294 if (allocation_sites_enabled && boilerplate->IsJSArray()) {
danno 2013/02/08 13:44:38 boilerplate->ShouldTrackAllocationInfo instead?, r
mvstanton 2013/02/11 11:11:24 It's helpful in other places in the code too, furt
5295 ElementsKind value_elements_kind = boilerplate->GetElementsKind();
5296 AllocationSiteMode mode = AllocationSiteInfo::GetMode(
5297 value_elements_kind);
5298 if (mode == TRACK_ALLOCATION_SITE) {
5299 *total_size += AllocationSiteInfo::kSize;
5300 }
5301 }
5302
5293 Handle<FixedArrayBase> elements(boilerplate->elements()); 5303 Handle<FixedArrayBase> elements(boilerplate->elements());
5294 if (elements->length() > 0 && 5304 if (elements->length() > 0 &&
5295 elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) { 5305 elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) {
5296 if (boilerplate->HasFastDoubleElements()) { 5306 if (boilerplate->HasFastDoubleElements()) {
5297 *total_size += FixedDoubleArray::SizeFor(elements->length()); 5307 *total_size += FixedDoubleArray::SizeFor(elements->length());
5298 } else if (boilerplate->HasFastObjectElements()) { 5308 } else if (boilerplate->HasFastObjectElements()) {
5299 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 5309 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
5300 int length = elements->length(); 5310 int length = elements->length();
5301 for (int i = 0; i < length; i++) { 5311 for (int i = 0; i < length; i++) {
5302 if ((*max_properties)-- == 0) return false; 5312 if ((*max_properties)-- == 0) return false;
5303 Handle<Object> value(fast_elements->get(i)); 5313 Handle<Object> value(fast_elements->get(i));
5304 if (value->IsJSObject()) { 5314 if (value->IsJSObject()) {
5305 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 5315 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
5306 if (!IsFastLiteral(value_object, 5316 if (!IsFastLiteral(value_object,
5307 max_depth - 1, 5317 max_depth - 1,
5308 max_properties, 5318 max_properties,
5309 total_size)) { 5319 total_size,
5320 allocation_sites_enabled)) {
5310 return false; 5321 return false;
5311 } 5322 }
5312 } 5323 }
5313 } 5324 }
5314 *total_size += FixedArray::SizeFor(length); 5325 *total_size += FixedArray::SizeFor(length);
5315 } else { 5326 } else {
5316 return false; 5327 return false;
5317 } 5328 }
5318 } 5329 }
5319 5330
5320 Handle<FixedArray> properties(boilerplate->properties()); 5331 Handle<FixedArray> properties(boilerplate->properties());
5321 if (properties->length() > 0) { 5332 if (properties->length() > 0) {
5322 return false; 5333 return false;
5323 } else { 5334 } else {
5324 int nof = boilerplate->map()->inobject_properties(); 5335 int nof = boilerplate->map()->inobject_properties();
5325 for (int i = 0; i < nof; i++) { 5336 for (int i = 0; i < nof; i++) {
5326 if ((*max_properties)-- == 0) return false; 5337 if ((*max_properties)-- == 0) return false;
5327 Handle<Object> value(boilerplate->InObjectPropertyAt(i)); 5338 Handle<Object> value(boilerplate->InObjectPropertyAt(i));
5328 if (value->IsJSObject()) { 5339 if (value->IsJSObject()) {
5329 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 5340 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
5330 if (!IsFastLiteral(value_object, 5341 if (!IsFastLiteral(value_object,
5331 max_depth - 1, 5342 max_depth - 1,
5332 max_properties, 5343 max_properties,
5333 total_size)) { 5344 total_size,
5345 allocation_sites_enabled)) {
5334 return false; 5346 return false;
5335 } 5347 }
5336 } 5348 }
5337 } 5349 }
5338 } 5350 }
5339 5351
5340 *total_size += boilerplate->map()->instance_size(); 5352 *total_size += boilerplate->map()->instance_size();
5341 return true; 5353 return true;
5342 } 5354 }
5343 5355
5344 5356
5345 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 5357 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
5346 ASSERT(!HasStackOverflow()); 5358 ASSERT(!HasStackOverflow());
5347 ASSERT(current_block() != NULL); 5359 ASSERT(current_block() != NULL);
5348 ASSERT(current_block()->HasPredecessor()); 5360 ASSERT(current_block()->HasPredecessor());
5349 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 5361 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
5350 HValue* context = environment()->LookupContext(); 5362 HValue* context = environment()->LookupContext();
5351 HInstruction* literal; 5363 HInstruction* literal;
5352 5364
5365 // We don't want to use AllocationSiteInfo when the object literal is
5366 // declared at global scope without a surrounding loop, that means it's
5367 // literal arrays will never be re-created, and therefore don't benefit from
5368 // site info.
5369 bool one_time_code = info()->scope()->is_global_scope() &&
5370 current_block()->LoopNestingDepth() == 0;
danno 2013/02/08 13:44:38 Maybe make this a predicate somewhere since you ca
mvstanton 2013/02/11 11:11:24 I made it a predicate on the FullCodeGenerator and
5371
5372 AllocationSiteMode mode = FLAG_track_allocation_sites && !one_time_code
5373 ? TRACK_ALLOCATION_SITE
5374 : DONT_TRACK_ALLOCATION_SITE;
5375
5353 // Check whether to use fast or slow deep-copying for boilerplate. 5376 // Check whether to use fast or slow deep-copying for boilerplate.
5354 int total_size = 0; 5377 int total_size = 0;
5355 int max_properties = HFastLiteral::kMaxLiteralProperties; 5378 int max_properties = HFastLiteral::kMaxLiteralProperties;
5356 Handle<Object> boilerplate(closure->literals()->get(expr->literal_index())); 5379 Handle<Object> original_boilerplate(closure->literals()->get(
5357 if (boilerplate->IsJSObject() && 5380 expr->literal_index()));
5358 IsFastLiteral(Handle<JSObject>::cast(boilerplate), 5381 if (original_boilerplate->IsJSObject() &&
5382 IsFastLiteral(Handle<JSObject>::cast(original_boilerplate),
5359 HFastLiteral::kMaxLiteralDepth, 5383 HFastLiteral::kMaxLiteralDepth,
5360 &max_properties, 5384 &max_properties,
5361 &total_size)) { 5385 &total_size,
5362 Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate); 5386 mode == TRACK_ALLOCATION_SITE)) {
5387 // Copy the boilerplate to prevent unsavory sharing between fullcodegen and
5388 // crankshaft.
5389 Handle<JSObject> original_boilerplate_object =
5390 Handle<JSObject>::cast(original_boilerplate);
5391 Handle<JSObject> boilerplate = DeepCopy(original_boilerplate_object);
5363 literal = new(zone()) HFastLiteral(context, 5392 literal = new(zone()) HFastLiteral(context,
5364 boilerplate_object, 5393 boilerplate,
5394 original_boilerplate_object,
5365 total_size, 5395 total_size,
5366 expr->literal_index(), 5396 expr->literal_index(),
5367 expr->depth(), 5397 expr->depth(),
5368 DONT_TRACK_ALLOCATION_SITE); 5398 mode);
5369 } else { 5399 } else {
5370 literal = new(zone()) HObjectLiteral(context, 5400 literal = new(zone()) HObjectLiteral(context,
5371 expr->constant_properties(), 5401 expr->constant_properties(),
5372 expr->fast_elements(), 5402 expr->fast_elements(),
5373 expr->literal_index(), 5403 expr->literal_index(),
5374 expr->depth(), 5404 expr->depth(),
5375 expr->has_function()); 5405 expr->has_function(),
5406 mode);
5376 } 5407 }
5377 5408
5378 // The object is expected in the bailout environment during computation 5409 // The object is expected in the bailout environment during computation
5379 // of the property values and is the value of the entire expression. 5410 // of the property values and is the value of the entire expression.
5380 PushAndAdd(literal); 5411 PushAndAdd(literal);
5381 5412
5382 expr->CalculateEmitStore(zone()); 5413 expr->CalculateEmitStore(zone());
5383 5414
5384 for (int i = 0; i < expr->properties()->length(); i++) { 5415 for (int i = 0; i < expr->properties()->length(); i++) {
5385 ObjectLiteral::Property* property = expr->properties()->at(i); 5416 ObjectLiteral::Property* property = expr->properties()->at(i);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
5450 5481
5451 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 5482 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
5452 ASSERT(!HasStackOverflow()); 5483 ASSERT(!HasStackOverflow());
5453 ASSERT(current_block() != NULL); 5484 ASSERT(current_block() != NULL);
5454 ASSERT(current_block()->HasPredecessor()); 5485 ASSERT(current_block()->HasPredecessor());
5455 ZoneList<Expression*>* subexprs = expr->values(); 5486 ZoneList<Expression*>* subexprs = expr->values();
5456 int length = subexprs->length(); 5487 int length = subexprs->length();
5457 HValue* context = environment()->LookupContext(); 5488 HValue* context = environment()->LookupContext();
5458 HInstruction* literal; 5489 HInstruction* literal;
5459 5490
5491 bool one_time_code = info()->scope()->is_global_scope() &&
5492 current_block()->LoopNestingDepth() == 0;
danno 2013/02/08 13:44:38 predicate for this
mvstanton 2013/02/11 11:11:24 Done.
5493
5494 AllocationSiteMode mode = FLAG_track_allocation_sites && !one_time_code
5495 ? TRACK_ALLOCATION_SITE
5496 : DONT_TRACK_ALLOCATION_SITE;
5497
5460 Handle<FixedArray> literals(environment()->closure()->literals()); 5498 Handle<FixedArray> literals(environment()->closure()->literals());
5461 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); 5499 Handle<Object> raw_boilerplate(literals->get(expr->literal_index()));
5462
5463 if (raw_boilerplate->IsUndefined()) { 5500 if (raw_boilerplate->IsUndefined()) {
5464 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( 5501 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate(
5465 isolate(), literals, expr->constant_elements()); 5502 isolate(), literals, expr->constant_elements());
5466 if (raw_boilerplate.is_null()) { 5503 if (raw_boilerplate.is_null()) {
5467 return Bailout("array boilerplate creation failed"); 5504 return Bailout("array boilerplate creation failed");
5468 } 5505 }
5469 literals->set(expr->literal_index(), *raw_boilerplate); 5506 literals->set(expr->literal_index(), *raw_boilerplate);
5470 if (JSObject::cast(*raw_boilerplate)->elements()->map() == 5507 if (JSObject::cast(*raw_boilerplate)->elements()->map() ==
5471 isolate()->heap()->fixed_cow_array_map()) { 5508 isolate()->heap()->fixed_cow_array_map()) {
5472 isolate()->counters()->cow_arrays_created_runtime()->Increment(); 5509 isolate()->counters()->cow_arrays_created_runtime()->Increment();
5473 } 5510 }
5474 } 5511 }
5475 5512
5476 Handle<JSObject> boilerplate = Handle<JSObject>::cast(raw_boilerplate); 5513 Handle<JSObject> original_boilerplate =
5514 Handle<JSObject>::cast(raw_boilerplate);
5477 ElementsKind boilerplate_elements_kind = 5515 ElementsKind boilerplate_elements_kind =
5478 Handle<JSObject>::cast(boilerplate)->GetElementsKind(); 5516 original_boilerplate->GetElementsKind();
5479
5480 // TODO(mvstanton): This heuristic is only a temporary solution. In the
5481 // end, we want to quit creating allocation site info after a certain number
5482 // of GCs for a call site.
5483 AllocationSiteMode mode = AllocationSiteInfo::GetMode(
5484 boilerplate_elements_kind);
5485 5517
5486 // Check whether to use fast or slow deep-copying for boilerplate. 5518 // Check whether to use fast or slow deep-copying for boilerplate.
5487 int total_size = 0; 5519 int total_size = 0;
5488 int max_properties = HFastLiteral::kMaxLiteralProperties; 5520 int max_properties = HFastLiteral::kMaxLiteralProperties;
5489 if (IsFastLiteral(boilerplate, 5521 if (IsFastLiteral(original_boilerplate,
5490 HFastLiteral::kMaxLiteralDepth, 5522 HFastLiteral::kMaxLiteralDepth,
5491 &max_properties, 5523 &max_properties,
5492 &total_size)) { 5524 &total_size,
5493 if (mode == TRACK_ALLOCATION_SITE) { 5525 mode == TRACK_ALLOCATION_SITE)) {
danno 2013/02/08 13:44:38 Pass mode rather than a boolean
mvstanton 2013/02/11 11:11:24 Done.
5494 total_size += AllocationSiteInfo::kSize; 5526 // Copy the boilerplate to prevent unsavory sharing between fullcodegen and
5495 } 5527 // crankshaft.
5528 Handle<JSObject> boilerplate = DeepCopy(original_boilerplate);
5496 literal = new(zone()) HFastLiteral(context, 5529 literal = new(zone()) HFastLiteral(context,
5497 boilerplate, 5530 boilerplate,
5531 original_boilerplate,
5498 total_size, 5532 total_size,
5499 expr->literal_index(), 5533 expr->literal_index(),
5500 expr->depth(), 5534 expr->depth(),
5501 mode); 5535 mode);
5502 } else { 5536 } else {
5503 literal = new(zone()) HArrayLiteral(context, 5537 literal = new(zone()) HArrayLiteral(context,
5504 boilerplate, 5538 original_boilerplate,
5505 length, 5539 length,
5506 expr->literal_index(), 5540 expr->literal_index(),
5507 expr->depth(), 5541 expr->depth(),
5508 mode); 5542 mode);
5509 } 5543 }
5510 5544
5511 // The array is expected in the bailout environment during computation 5545 // The array is expected in the bailout environment during computation
5512 // of the property values and is the value of the entire expression. 5546 // of the property values and is the value of the entire expression.
5513 PushAndAdd(literal); 5547 PushAndAdd(literal);
5514 5548
(...skipping 4869 matching lines...) Expand 10 before | Expand all | Expand 10 after
10384 } 10418 }
10385 } 10419 }
10386 10420
10387 #ifdef DEBUG 10421 #ifdef DEBUG
10388 if (graph_ != NULL) graph_->Verify(false); // No full verify. 10422 if (graph_ != NULL) graph_->Verify(false); // No full verify.
10389 if (allocator_ != NULL) allocator_->Verify(); 10423 if (allocator_ != NULL) allocator_->Verify();
10390 #endif 10424 #endif
10391 } 10425 }
10392 10426
10393 } } // namespace v8::internal 10427 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698