OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 12 matching lines...) Expand all Loading... |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "hydrogen.h" | 28 #include "hydrogen.h" |
29 | 29 |
30 #include <algorithm> | 30 #include <algorithm> |
31 | 31 |
32 #include "v8.h" | 32 #include "v8.h" |
| 33 #include "allocation-site-scopes.h" |
33 #include "codegen.h" | 34 #include "codegen.h" |
34 #include "full-codegen.h" | 35 #include "full-codegen.h" |
35 #include "hashmap.h" | 36 #include "hashmap.h" |
36 #include "hydrogen-bce.h" | 37 #include "hydrogen-bce.h" |
37 #include "hydrogen-bch.h" | 38 #include "hydrogen-bch.h" |
38 #include "hydrogen-canonicalize.h" | 39 #include "hydrogen-canonicalize.h" |
39 #include "hydrogen-check-elimination.h" | 40 #include "hydrogen-check-elimination.h" |
40 #include "hydrogen-dce.h" | 41 #include "hydrogen-dce.h" |
41 #include "hydrogen-dehoist.h" | 42 #include "hydrogen-dehoist.h" |
42 #include "hydrogen-environment-liveness.h" | 43 #include "hydrogen-environment-liveness.h" |
(...skipping 4298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4341 Handle<JSObject> boilerplate; | 4342 Handle<JSObject> boilerplate; |
4342 if (!literals_cell->IsUndefined()) { | 4343 if (!literals_cell->IsUndefined()) { |
4343 // Retrieve the boilerplate | 4344 // Retrieve the boilerplate |
4344 site = Handle<AllocationSite>::cast(literals_cell); | 4345 site = Handle<AllocationSite>::cast(literals_cell); |
4345 boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), | 4346 boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), |
4346 isolate()); | 4347 isolate()); |
4347 } | 4348 } |
4348 | 4349 |
4349 if (!boilerplate.is_null() && | 4350 if (!boilerplate.is_null() && |
4350 IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { | 4351 IsFastLiteral(boilerplate, kMaxFastLiteralDepth, &max_properties)) { |
4351 literal = BuildFastLiteral(boilerplate); | 4352 AllocationSiteContext site_context(isolate(), false); |
| 4353 AllocationSiteUsageScope site_scope(&site_context, site, boilerplate); |
| 4354 literal = BuildFastLiteral(boilerplate, &site_context); |
4352 } else { | 4355 } else { |
4353 NoObservableSideEffectsScope no_effects(this); | 4356 NoObservableSideEffectsScope no_effects(this); |
4354 Handle<FixedArray> closure_literals(closure->literals(), isolate()); | 4357 Handle<FixedArray> closure_literals(closure->literals(), isolate()); |
4355 Handle<FixedArray> constant_properties = expr->constant_properties(); | 4358 Handle<FixedArray> constant_properties = expr->constant_properties(); |
4356 int literal_index = expr->literal_index(); | 4359 int literal_index = expr->literal_index(); |
4357 int flags = expr->fast_elements() | 4360 int flags = expr->fast_elements() |
4358 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; | 4361 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; |
4359 flags |= expr->has_function() | 4362 flags |= expr->has_function() |
4360 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; | 4363 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; |
4361 | 4364 |
4362 Add<HPushArgument>(Add<HConstant>(closure_literals)); | 4365 Add<HPushArgument>(Add<HConstant>(closure_literals)); |
4363 Add<HPushArgument>(Add<HConstant>(literal_index)); | 4366 Add<HPushArgument>(Add<HConstant>(literal_index)); |
4364 Add<HPushArgument>(Add<HConstant>(constant_properties)); | 4367 Add<HPushArgument>(Add<HConstant>(constant_properties)); |
4365 Add<HPushArgument>(Add<HConstant>(flags)); | 4368 Add<HPushArgument>(Add<HConstant>(flags)); |
4366 | 4369 |
| 4370 // TODO(mvstanton): Add a flag to turn off creation of any |
| 4371 // AllocationMementos for this call: we are in crankshaft and should have |
| 4372 // learned enough about transition behavior to stop emitting mementos. |
4367 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; | 4373 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; |
4368 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 4374 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
4369 Runtime::FunctionForId(function_id), | 4375 Runtime::FunctionForId(function_id), |
4370 4); | 4376 4); |
4371 } | 4377 } |
4372 | 4378 |
4373 // The object is expected in the bailout environment during computation | 4379 // The object is expected in the bailout environment during computation |
4374 // of the property values and is the value of the entire expression. | 4380 // of the property values and is the value of the entire expression. |
4375 Push(literal); | 4381 Push(literal); |
4376 | 4382 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4456 isolate()); | 4462 isolate()); |
4457 Handle<Object> raw_boilerplate; | 4463 Handle<Object> raw_boilerplate; |
4458 if (literals_cell->IsUndefined()) { | 4464 if (literals_cell->IsUndefined()) { |
4459 uninitialized = true; | 4465 uninitialized = true; |
4460 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( | 4466 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( |
4461 isolate(), literals, expr->constant_elements()); | 4467 isolate(), literals, expr->constant_elements()); |
4462 if (raw_boilerplate.is_null()) { | 4468 if (raw_boilerplate.is_null()) { |
4463 return Bailout(kArrayBoilerplateCreationFailed); | 4469 return Bailout(kArrayBoilerplateCreationFailed); |
4464 } | 4470 } |
4465 | 4471 |
4466 site = isolate()->factory()->NewAllocationSite(); | 4472 AllocationSiteContext site_context(isolate(), true); |
4467 site->set_transition_info(*raw_boilerplate); | 4473 AllocationSiteCreationScope site_scope(&site_context); |
| 4474 Handle<Object> same = JSObject::DeepWalk( |
| 4475 Handle<JSObject>::cast(raw_boilerplate), &site_context); |
| 4476 site = site_context.top(); |
| 4477 site->set_transition_info(*same); |
4468 literals->set(expr->literal_index(), *site); | 4478 literals->set(expr->literal_index(), *site); |
4469 | 4479 |
4470 if (JSObject::cast(*raw_boilerplate)->elements()->map() == | 4480 if (JSObject::cast(*raw_boilerplate)->elements()->map() == |
4471 isolate()->heap()->fixed_cow_array_map()) { | 4481 isolate()->heap()->fixed_cow_array_map()) { |
4472 isolate()->counters()->cow_arrays_created_runtime()->Increment(); | 4482 isolate()->counters()->cow_arrays_created_runtime()->Increment(); |
4473 } | 4483 } |
4474 } else { | 4484 } else { |
4475 ASSERT(literals_cell->IsAllocationSite()); | 4485 ASSERT(literals_cell->IsAllocationSite()); |
4476 site = Handle<AllocationSite>::cast(literals_cell); | 4486 site = Handle<AllocationSite>::cast(literals_cell); |
4477 raw_boilerplate = Handle<Object>(site->transition_info(), isolate()); | 4487 raw_boilerplate = Handle<Object>(site->transition_info(), isolate()); |
4478 } | 4488 } |
4479 | 4489 |
4480 ASSERT(!raw_boilerplate.is_null()); | 4490 ASSERT(!raw_boilerplate.is_null()); |
4481 ASSERT(site->IsLiteralSite()); | 4491 ASSERT(site->SitePointsToLiteral()); |
4482 | 4492 |
4483 Handle<JSObject> boilerplate_object = | 4493 Handle<JSObject> boilerplate_object = |
4484 Handle<JSObject>::cast(raw_boilerplate); | 4494 Handle<JSObject>::cast(raw_boilerplate); |
4485 ElementsKind boilerplate_elements_kind = | 4495 ElementsKind boilerplate_elements_kind = |
4486 Handle<JSObject>::cast(boilerplate_object)->GetElementsKind(); | 4496 Handle<JSObject>::cast(boilerplate_object)->GetElementsKind(); |
4487 | 4497 |
4488 ASSERT(AllocationSite::CanTrack(boilerplate_object->map()->instance_type())); | |
4489 | |
4490 // Check whether to use fast or slow deep-copying for boilerplate. | 4498 // Check whether to use fast or slow deep-copying for boilerplate. |
4491 int max_properties = kMaxFastLiteralProperties; | 4499 int max_properties = kMaxFastLiteralProperties; |
4492 if (IsFastLiteral(boilerplate_object, | 4500 if (IsFastLiteral(boilerplate_object, |
4493 kMaxFastLiteralDepth, | 4501 kMaxFastLiteralDepth, |
4494 &max_properties)) { | 4502 &max_properties)) { |
4495 literal = BuildFastLiteral(boilerplate_object); | 4503 AllocationSiteContext site_context(isolate(), false); |
| 4504 AllocationSiteUsageScope site_scope(&site_context, site, |
| 4505 boilerplate_object); |
| 4506 literal = BuildFastLiteral(boilerplate_object, &site_context); |
4496 } else { | 4507 } else { |
4497 NoObservableSideEffectsScope no_effects(this); | 4508 NoObservableSideEffectsScope no_effects(this); |
4498 // Boilerplate already exists and constant elements are never accessed, | 4509 // Boilerplate already exists and constant elements are never accessed, |
4499 // pass an empty fixed array to the runtime function instead. | 4510 // pass an empty fixed array to the runtime function instead. |
4500 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); | 4511 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); |
4501 int literal_index = expr->literal_index(); | 4512 int literal_index = expr->literal_index(); |
4502 | 4513 |
4503 Add<HPushArgument>(Add<HConstant>(literals)); | 4514 Add<HPushArgument>(Add<HConstant>(literals)); |
4504 Add<HPushArgument>(Add<HConstant>(literal_index)); | 4515 Add<HPushArgument>(Add<HConstant>(literal_index)); |
4505 Add<HPushArgument>(Add<HConstant>(constants)); | 4516 Add<HPushArgument>(Add<HConstant>(constants)); |
4506 | 4517 |
| 4518 // TODO(mvstanton): Consider a flag to turn off creation of any |
| 4519 // AllocationMementos for this call: we are in crankshaft and should have |
| 4520 // learned enough about transition behavior to stop emitting mementos. |
4507 Runtime::FunctionId function_id = (expr->depth() > 1) | 4521 Runtime::FunctionId function_id = (expr->depth() > 1) |
4508 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; | 4522 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; |
4509 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 4523 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
4510 Runtime::FunctionForId(function_id), | 4524 Runtime::FunctionForId(function_id), |
4511 3); | 4525 3); |
4512 | 4526 |
4513 // De-opt if elements kind changed from boilerplate_elements_kind. | 4527 // De-opt if elements kind changed from boilerplate_elements_kind. |
4514 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); | 4528 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); |
4515 literal = Add<HCheckMaps>(literal, map, top_info()); | 4529 literal = Add<HCheckMaps>(literal, map, top_info()); |
4516 } | 4530 } |
(...skipping 3889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8406 if (function_state()->outer() != NULL) { | 8420 if (function_state()->outer() != NULL) { |
8407 return New<HConstant>( | 8421 return New<HConstant>( |
8408 function_state()->compilation_info()->closure()); | 8422 function_state()->compilation_info()->closure()); |
8409 } else { | 8423 } else { |
8410 return new(zone()) HThisFunction; | 8424 return new(zone()) HThisFunction; |
8411 } | 8425 } |
8412 } | 8426 } |
8413 | 8427 |
8414 | 8428 |
8415 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 8429 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
8416 Handle<JSObject> boilerplate_object) { | 8430 Handle<JSObject> boilerplate_object, |
| 8431 AllocationSiteContext* site_context) { |
8417 NoObservableSideEffectsScope no_effects(this); | 8432 NoObservableSideEffectsScope no_effects(this); |
8418 InstanceType instance_type = boilerplate_object->map()->instance_type(); | 8433 InstanceType instance_type = boilerplate_object->map()->instance_type(); |
8419 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); | 8434 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); |
8420 | 8435 |
8421 HType type = instance_type == JS_ARRAY_TYPE | 8436 HType type = instance_type == JS_ARRAY_TYPE |
8422 ? HType::JSArray() : HType::JSObject(); | 8437 ? HType::JSArray() : HType::JSObject(); |
8423 HValue* object_size_constant = Add<HConstant>( | 8438 HValue* object_size_constant = Add<HConstant>( |
8424 boilerplate_object->map()->instance_size()); | 8439 boilerplate_object->map()->instance_size()); |
8425 HInstruction* object = Add<HAllocate>(object_size_constant, type, | 8440 HInstruction* object = Add<HAllocate>(object_size_constant, type, |
8426 isolate()->heap()->GetPretenureMode(), instance_type); | 8441 isolate()->heap()->GetPretenureMode(), instance_type); |
(...skipping 11 matching lines...) Expand all Loading... |
8438 if (boilerplate_object->HasFastDoubleElements()) { | 8453 if (boilerplate_object->HasFastDoubleElements()) { |
8439 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 8454 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
8440 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE); | 8455 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE); |
8441 } else { | 8456 } else { |
8442 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 8457 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
8443 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE); | 8458 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE); |
8444 } | 8459 } |
8445 } | 8460 } |
8446 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); | 8461 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); |
8447 | 8462 |
8448 | |
8449 // Copy object elements if non-COW. | 8463 // Copy object elements if non-COW. |
8450 if (object_elements != NULL) { | 8464 if (object_elements != NULL) { |
8451 BuildEmitElements(boilerplate_object, elements, object_elements); | 8465 BuildEmitElements(boilerplate_object, elements, object_elements, |
| 8466 site_context); |
8452 } | 8467 } |
8453 | 8468 |
8454 // Copy in-object properties. | 8469 // Copy in-object properties. |
8455 if (boilerplate_object->map()->NumberOfFields() != 0) { | 8470 if (boilerplate_object->map()->NumberOfFields() != 0) { |
8456 BuildEmitInObjectProperties(boilerplate_object, object); | 8471 BuildEmitInObjectProperties(boilerplate_object, object, site_context); |
8457 } | 8472 } |
8458 return object; | 8473 return object; |
8459 } | 8474 } |
8460 | 8475 |
8461 | 8476 |
8462 void HOptimizedGraphBuilder::BuildEmitObjectHeader( | 8477 void HOptimizedGraphBuilder::BuildEmitObjectHeader( |
8463 Handle<JSObject> boilerplate_object, | 8478 Handle<JSObject> boilerplate_object, |
8464 HInstruction* object) { | 8479 HInstruction* object) { |
8465 ASSERT(boilerplate_object->properties()->length() == 0); | 8480 ASSERT(boilerplate_object->properties()->length() == 0); |
8466 | 8481 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8498 Handle<Object>(boilerplate_object->elements(), isolate()); | 8513 Handle<Object>(boilerplate_object->elements(), isolate()); |
8499 object_elements = Add<HConstant>(elements_field); | 8514 object_elements = Add<HConstant>(elements_field); |
8500 } | 8515 } |
8501 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 8516 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
8502 object_elements); | 8517 object_elements); |
8503 } | 8518 } |
8504 | 8519 |
8505 | 8520 |
8506 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( | 8521 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
8507 Handle<JSObject> boilerplate_object, | 8522 Handle<JSObject> boilerplate_object, |
8508 HInstruction* object) { | 8523 HInstruction* object, |
| 8524 AllocationSiteContext* site_context) { |
8509 Handle<DescriptorArray> descriptors( | 8525 Handle<DescriptorArray> descriptors( |
8510 boilerplate_object->map()->instance_descriptors()); | 8526 boilerplate_object->map()->instance_descriptors()); |
8511 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); | 8527 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
8512 | 8528 |
8513 int copied_fields = 0; | 8529 int copied_fields = 0; |
8514 for (int i = 0; i < limit; i++) { | 8530 for (int i = 0; i < limit; i++) { |
8515 PropertyDetails details = descriptors->GetDetails(i); | 8531 PropertyDetails details = descriptors->GetDetails(i); |
8516 if (details.type() != FIELD) continue; | 8532 if (details.type() != FIELD) continue; |
8517 copied_fields++; | 8533 copied_fields++; |
8518 int index = descriptors->GetFieldIndex(i); | 8534 int index = descriptors->GetFieldIndex(i); |
8519 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); | 8535 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
8520 Handle<Name> name(descriptors->GetKey(i)); | 8536 Handle<Name> name(descriptors->GetKey(i)); |
8521 Handle<Object> value = | 8537 Handle<Object> value = |
8522 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), | 8538 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
8523 isolate()); | 8539 isolate()); |
8524 | 8540 |
8525 // The access for the store depends on the type of the boilerplate. | 8541 // The access for the store depends on the type of the boilerplate. |
8526 HObjectAccess access = boilerplate_object->IsJSArray() ? | 8542 HObjectAccess access = boilerplate_object->IsJSArray() ? |
8527 HObjectAccess::ForJSArrayOffset(property_offset) : | 8543 HObjectAccess::ForJSArrayOffset(property_offset) : |
8528 HObjectAccess::ForJSObjectOffset(property_offset); | 8544 HObjectAccess::ForJSObjectOffset(property_offset); |
8529 | 8545 |
8530 if (value->IsJSObject()) { | 8546 if (value->IsJSObject()) { |
| 8547 AllocationSiteUsageScope site_scope(site_context, value); |
8531 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 8548 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
8532 HInstruction* result = BuildFastLiteral(value_object); | 8549 HInstruction* result = |
| 8550 BuildFastLiteral(value_object, site_context); |
8533 Add<HStoreNamedField>(object, access, result); | 8551 Add<HStoreNamedField>(object, access, result); |
8534 } else { | 8552 } else { |
8535 Representation representation = details.representation(); | 8553 Representation representation = details.representation(); |
8536 HInstruction* value_instruction = Add<HConstant>(value); | 8554 HInstruction* value_instruction = Add<HConstant>(value); |
8537 | 8555 |
8538 if (representation.IsDouble()) { | 8556 if (representation.IsDouble()) { |
8539 // Allocate a HeapNumber box and store the value into it. | 8557 // Allocate a HeapNumber box and store the value into it. |
8540 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); | 8558 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); |
| 8559 // TODO(mvstanton): This heap number alloc does not have a corresponding |
| 8560 // AllocationSite. That is okay because |
| 8561 // 1) it's a child object of another object with a valid allocation site |
| 8562 // 2) we can just use the mode of the parent object for pretenuring |
| 8563 // The todo is replace GetPretenureMode() with |
| 8564 // site_context->top()->GetPretenureMode(). |
8541 HInstruction* double_box = | 8565 HInstruction* double_box = |
8542 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), | 8566 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), |
8543 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE); | 8567 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE); |
8544 AddStoreMapConstant(double_box, | 8568 AddStoreMapConstant(double_box, |
8545 isolate()->factory()->heap_number_map()); | 8569 isolate()->factory()->heap_number_map()); |
8546 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), | 8570 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), |
8547 value_instruction); | 8571 value_instruction); |
8548 value_instruction = double_box; | 8572 value_instruction = double_box; |
8549 } | 8573 } |
8550 | 8574 |
8551 Add<HStoreNamedField>(object, access, value_instruction); | 8575 Add<HStoreNamedField>(object, access, value_instruction); |
8552 } | 8576 } |
8553 } | 8577 } |
8554 | 8578 |
8555 int inobject_properties = boilerplate_object->map()->inobject_properties(); | 8579 int inobject_properties = boilerplate_object->map()->inobject_properties(); |
8556 HInstruction* value_instruction = | 8580 HInstruction* value_instruction = |
8557 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); | 8581 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); |
8558 for (int i = copied_fields; i < inobject_properties; i++) { | 8582 for (int i = copied_fields; i < inobject_properties; i++) { |
8559 ASSERT(boilerplate_object->IsJSObject()); | 8583 ASSERT(boilerplate_object->IsJSObject()); |
8560 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); | 8584 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); |
8561 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); | 8585 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); |
8562 Add<HStoreNamedField>(object, access, value_instruction); | 8586 Add<HStoreNamedField>(object, access, value_instruction); |
8563 } | 8587 } |
8564 } | 8588 } |
8565 | 8589 |
8566 | 8590 |
8567 void HOptimizedGraphBuilder::BuildEmitElements( | 8591 void HOptimizedGraphBuilder::BuildEmitElements( |
8568 Handle<JSObject> boilerplate_object, | 8592 Handle<JSObject> boilerplate_object, |
8569 Handle<FixedArrayBase> elements, | 8593 Handle<FixedArrayBase> elements, |
8570 HValue* object_elements) { | 8594 HValue* object_elements, |
| 8595 AllocationSiteContext* site_context) { |
8571 ElementsKind kind = boilerplate_object->map()->elements_kind(); | 8596 ElementsKind kind = boilerplate_object->map()->elements_kind(); |
8572 int elements_length = elements->length(); | 8597 int elements_length = elements->length(); |
8573 HValue* object_elements_length = Add<HConstant>(elements_length); | 8598 HValue* object_elements_length = Add<HConstant>(elements_length); |
8574 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); | 8599 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); |
8575 | 8600 |
8576 // Copy elements backing store content. | 8601 // Copy elements backing store content. |
8577 if (elements->IsFixedDoubleArray()) { | 8602 if (elements->IsFixedDoubleArray()) { |
8578 BuildEmitFixedDoubleArray(elements, kind, object_elements); | 8603 BuildEmitFixedDoubleArray(elements, kind, object_elements); |
8579 } else if (elements->IsFixedArray()) { | 8604 } else if (elements->IsFixedArray()) { |
8580 BuildEmitFixedArray(elements, kind, object_elements); | 8605 BuildEmitFixedArray(elements, kind, object_elements, |
| 8606 site_context); |
8581 } else { | 8607 } else { |
8582 UNREACHABLE(); | 8608 UNREACHABLE(); |
8583 } | 8609 } |
8584 } | 8610 } |
8585 | 8611 |
8586 | 8612 |
8587 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 8613 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
8588 Handle<FixedArrayBase> elements, | 8614 Handle<FixedArrayBase> elements, |
8589 ElementsKind kind, | 8615 ElementsKind kind, |
8590 HValue* object_elements) { | 8616 HValue* object_elements) { |
8591 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 8617 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
8592 int elements_length = elements->length(); | 8618 int elements_length = elements->length(); |
8593 for (int i = 0; i < elements_length; i++) { | 8619 for (int i = 0; i < elements_length; i++) { |
8594 HValue* key_constant = Add<HConstant>(i); | 8620 HValue* key_constant = Add<HConstant>(i); |
8595 HInstruction* value_instruction = | 8621 HInstruction* value_instruction = |
8596 Add<HLoadKeyed>(boilerplate_elements, key_constant, | 8622 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
8597 static_cast<HValue*>(NULL), kind, | 8623 static_cast<HValue*>(NULL), kind, |
8598 ALLOW_RETURN_HOLE); | 8624 ALLOW_RETURN_HOLE); |
8599 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, | 8625 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, |
8600 value_instruction, kind); | 8626 value_instruction, kind); |
8601 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 8627 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
8602 } | 8628 } |
8603 } | 8629 } |
8604 | 8630 |
8605 | 8631 |
8606 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 8632 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
8607 Handle<FixedArrayBase> elements, | 8633 Handle<FixedArrayBase> elements, |
8608 ElementsKind kind, | 8634 ElementsKind kind, |
8609 HValue* object_elements) { | 8635 HValue* object_elements, |
| 8636 AllocationSiteContext* site_context) { |
8610 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 8637 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
8611 int elements_length = elements->length(); | 8638 int elements_length = elements->length(); |
8612 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 8639 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
8613 for (int i = 0; i < elements_length; i++) { | 8640 for (int i = 0; i < elements_length; i++) { |
8614 Handle<Object> value(fast_elements->get(i), isolate()); | 8641 Handle<Object> value(fast_elements->get(i), isolate()); |
8615 HValue* key_constant = Add<HConstant>(i); | 8642 HValue* key_constant = Add<HConstant>(i); |
8616 if (value->IsJSObject()) { | 8643 if (value->IsJSObject()) { |
| 8644 AllocationSiteUsageScope site_scope(site_context, value); |
8617 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 8645 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
8618 HInstruction* result = BuildFastLiteral(value_object); | 8646 HInstruction* result = |
| 8647 BuildFastLiteral(value_object, site_context); |
8619 Add<HStoreKeyed>(object_elements, key_constant, result, kind); | 8648 Add<HStoreKeyed>(object_elements, key_constant, result, kind); |
8620 } else { | 8649 } else { |
8621 HInstruction* value_instruction = | 8650 HInstruction* value_instruction = |
8622 Add<HLoadKeyed>(boilerplate_elements, key_constant, | 8651 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
8623 static_cast<HValue*>(NULL), kind, | 8652 static_cast<HValue*>(NULL), kind, |
8624 ALLOW_RETURN_HOLE); | 8653 ALLOW_RETURN_HOLE); |
8625 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); | 8654 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); |
8626 } | 8655 } |
8627 } | 8656 } |
8628 } | 8657 } |
(...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9880 if (ShouldProduceTraceOutput()) { | 9909 if (ShouldProduceTraceOutput()) { |
9881 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9910 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9882 } | 9911 } |
9883 | 9912 |
9884 #ifdef DEBUG | 9913 #ifdef DEBUG |
9885 graph_->Verify(false); // No full verify. | 9914 graph_->Verify(false); // No full verify. |
9886 #endif | 9915 #endif |
9887 } | 9916 } |
9888 | 9917 |
9889 } } // namespace v8::internal | 9918 } } // namespace v8::internal |
OLD | NEW |