| 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 4299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 literal = BuildFastLiteral(boilerplate); |
| 4353 AllocationSiteContext site_context(isolate(), false); |
| 4354 AllocationSiteUsageScope site_scope(&site_context, site, boilerplate); |
| 4355 literal = BuildFastLiteral(boilerplate, &site_context); |
| 4352 } else { | 4356 } else { |
| 4353 NoObservableSideEffectsScope no_effects(this); | 4357 NoObservableSideEffectsScope no_effects(this); |
| 4354 Handle<FixedArray> closure_literals(closure->literals(), isolate()); | 4358 Handle<FixedArray> closure_literals(closure->literals(), isolate()); |
| 4355 Handle<FixedArray> constant_properties = expr->constant_properties(); | 4359 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 4356 int literal_index = expr->literal_index(); | 4360 int literal_index = expr->literal_index(); |
| 4357 int flags = expr->fast_elements() | 4361 int flags = expr->fast_elements() |
| 4358 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; | 4362 ? ObjectLiteral::kFastElements : ObjectLiteral::kNoFlags; |
| 4359 flags |= expr->has_function() | 4363 flags |= expr->has_function() |
| 4360 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; | 4364 ? ObjectLiteral::kHasFunction : ObjectLiteral::kNoFlags; |
| 4361 | 4365 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4456 isolate()); | 4460 isolate()); |
| 4457 Handle<Object> raw_boilerplate; | 4461 Handle<Object> raw_boilerplate; |
| 4458 if (literals_cell->IsUndefined()) { | 4462 if (literals_cell->IsUndefined()) { |
| 4459 uninitialized = true; | 4463 uninitialized = true; |
| 4460 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( | 4464 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( |
| 4461 isolate(), literals, expr->constant_elements()); | 4465 isolate(), literals, expr->constant_elements()); |
| 4462 if (raw_boilerplate.is_null()) { | 4466 if (raw_boilerplate.is_null()) { |
| 4463 return Bailout(kArrayBoilerplateCreationFailed); | 4467 return Bailout(kArrayBoilerplateCreationFailed); |
| 4464 } | 4468 } |
| 4465 | 4469 |
| 4466 site = isolate()->factory()->NewAllocationSite(); | 4470 AllocationSiteContext site_context(isolate(), true); |
| 4467 site->set_transition_info(*raw_boilerplate); | 4471 AllocationSiteCreationScope site_scope(&site_context); |
| 4472 Handle<Object> same = JSObject::DeepWalk( |
| 4473 Handle<JSObject>::cast(raw_boilerplate), &site_context); |
| 4474 site = site_context.top(); |
| 4475 site->set_transition_info(*same); |
| 4468 literals->set(expr->literal_index(), *site); | 4476 literals->set(expr->literal_index(), *site); |
| 4469 | 4477 |
| 4470 if (JSObject::cast(*raw_boilerplate)->elements()->map() == | 4478 if (JSObject::cast(*raw_boilerplate)->elements()->map() == |
| 4471 isolate()->heap()->fixed_cow_array_map()) { | 4479 isolate()->heap()->fixed_cow_array_map()) { |
| 4472 isolate()->counters()->cow_arrays_created_runtime()->Increment(); | 4480 isolate()->counters()->cow_arrays_created_runtime()->Increment(); |
| 4473 } | 4481 } |
| 4474 } else { | 4482 } else { |
| 4475 ASSERT(literals_cell->IsAllocationSite()); | 4483 ASSERT(literals_cell->IsAllocationSite()); |
| 4476 site = Handle<AllocationSite>::cast(literals_cell); | 4484 site = Handle<AllocationSite>::cast(literals_cell); |
| 4477 raw_boilerplate = Handle<Object>(site->transition_info(), isolate()); | 4485 raw_boilerplate = Handle<Object>(site->transition_info(), isolate()); |
| 4478 } | 4486 } |
| 4479 | 4487 |
| 4480 ASSERT(!raw_boilerplate.is_null()); | 4488 ASSERT(!raw_boilerplate.is_null()); |
| 4481 ASSERT(site->IsLiteralSite()); | 4489 ASSERT(site->IsLiteralSite()); |
| 4482 | 4490 |
| 4483 Handle<JSObject> boilerplate_object = | 4491 Handle<JSObject> boilerplate_object = |
| 4484 Handle<JSObject>::cast(raw_boilerplate); | 4492 Handle<JSObject>::cast(raw_boilerplate); |
| 4485 ElementsKind boilerplate_elements_kind = | 4493 ElementsKind boilerplate_elements_kind = |
| 4486 Handle<JSObject>::cast(boilerplate_object)->GetElementsKind(); | 4494 Handle<JSObject>::cast(boilerplate_object)->GetElementsKind(); |
| 4487 | 4495 |
| 4488 ASSERT(AllocationSite::CanTrack(boilerplate_object->map()->instance_type())); | |
| 4489 | |
| 4490 // Check whether to use fast or slow deep-copying for boilerplate. | 4496 // Check whether to use fast or slow deep-copying for boilerplate. |
| 4491 int max_properties = kMaxFastLiteralProperties; | 4497 int max_properties = kMaxFastLiteralProperties; |
| 4492 if (IsFastLiteral(boilerplate_object, | 4498 if (IsFastLiteral(boilerplate_object, |
| 4493 kMaxFastLiteralDepth, | 4499 kMaxFastLiteralDepth, |
| 4494 &max_properties)) { | 4500 &max_properties)) { |
| 4495 literal = BuildFastLiteral(boilerplate_object); | 4501 AllocationSiteContext site_context(isolate(), false); |
| 4502 AllocationSiteUsageScope site_scope(&site_context, site, |
| 4503 boilerplate_object); |
| 4504 literal = BuildFastLiteral(boilerplate_object, &site_context); |
| 4496 } else { | 4505 } else { |
| 4497 NoObservableSideEffectsScope no_effects(this); | 4506 NoObservableSideEffectsScope no_effects(this); |
| 4498 // Boilerplate already exists and constant elements are never accessed, | 4507 // Boilerplate already exists and constant elements are never accessed, |
| 4499 // pass an empty fixed array to the runtime function instead. | 4508 // pass an empty fixed array to the runtime function instead. |
| 4500 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); | 4509 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); |
| 4501 int literal_index = expr->literal_index(); | 4510 int literal_index = expr->literal_index(); |
| 4502 | 4511 |
| 4503 Add<HPushArgument>(Add<HConstant>(literals)); | 4512 Add<HPushArgument>(Add<HConstant>(literals)); |
| 4504 Add<HPushArgument>(Add<HConstant>(literal_index)); | 4513 Add<HPushArgument>(Add<HConstant>(literal_index)); |
| 4505 Add<HPushArgument>(Add<HConstant>(constants)); | 4514 Add<HPushArgument>(Add<HConstant>(constants)); |
| (...skipping 3900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8406 if (function_state()->outer() != NULL) { | 8415 if (function_state()->outer() != NULL) { |
| 8407 return New<HConstant>( | 8416 return New<HConstant>( |
| 8408 function_state()->compilation_info()->closure()); | 8417 function_state()->compilation_info()->closure()); |
| 8409 } else { | 8418 } else { |
| 8410 return new(zone()) HThisFunction; | 8419 return new(zone()) HThisFunction; |
| 8411 } | 8420 } |
| 8412 } | 8421 } |
| 8413 | 8422 |
| 8414 | 8423 |
| 8415 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 8424 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
| 8416 Handle<JSObject> boilerplate_object) { | 8425 Handle<JSObject> boilerplate_object, |
| 8426 AllocationSiteContext* site_context) { |
| 8417 NoObservableSideEffectsScope no_effects(this); | 8427 NoObservableSideEffectsScope no_effects(this); |
| 8418 InstanceType instance_type = boilerplate_object->map()->instance_type(); | 8428 InstanceType instance_type = boilerplate_object->map()->instance_type(); |
| 8419 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); | 8429 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); |
| 8420 | 8430 |
| 8421 HType type = instance_type == JS_ARRAY_TYPE | 8431 HType type = instance_type == JS_ARRAY_TYPE |
| 8422 ? HType::JSArray() : HType::JSObject(); | 8432 ? HType::JSArray() : HType::JSObject(); |
| 8423 HValue* object_size_constant = Add<HConstant>( | 8433 HValue* object_size_constant = Add<HConstant>( |
| 8424 boilerplate_object->map()->instance_size()); | 8434 boilerplate_object->map()->instance_size()); |
| 8425 HInstruction* object = Add<HAllocate>(object_size_constant, type, | 8435 HInstruction* object = Add<HAllocate>(object_size_constant, type, |
| 8426 isolate()->heap()->GetPretenureMode(), instance_type); | 8436 isolate()->heap()->GetPretenureMode(), instance_type); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 8438 if (boilerplate_object->HasFastDoubleElements()) { | 8448 if (boilerplate_object->HasFastDoubleElements()) { |
| 8439 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 8449 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
| 8440 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE); | 8450 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE); |
| 8441 } else { | 8451 } else { |
| 8442 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 8452 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
| 8443 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE); | 8453 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE); |
| 8444 } | 8454 } |
| 8445 } | 8455 } |
| 8446 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); | 8456 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); |
| 8447 | 8457 |
| 8448 | |
| 8449 // Copy object elements if non-COW. | 8458 // Copy object elements if non-COW. |
| 8450 if (object_elements != NULL) { | 8459 if (object_elements != NULL) { |
| 8451 BuildEmitElements(boilerplate_object, elements, object_elements); | 8460 BuildEmitElements(boilerplate_object, elements, object_elements, |
| 8461 site_context); |
| 8452 } | 8462 } |
| 8453 | 8463 |
| 8454 // Copy in-object properties. | 8464 // Copy in-object properties. |
| 8455 if (boilerplate_object->map()->NumberOfFields() != 0) { | 8465 if (boilerplate_object->map()->NumberOfFields() != 0) { |
| 8456 BuildEmitInObjectProperties(boilerplate_object, object); | 8466 BuildEmitInObjectProperties(boilerplate_object, object, site_context); |
| 8457 } | 8467 } |
| 8458 return object; | 8468 return object; |
| 8459 } | 8469 } |
| 8460 | 8470 |
| 8461 | 8471 |
| 8462 void HOptimizedGraphBuilder::BuildEmitObjectHeader( | 8472 void HOptimizedGraphBuilder::BuildEmitObjectHeader( |
| 8463 Handle<JSObject> boilerplate_object, | 8473 Handle<JSObject> boilerplate_object, |
| 8464 HInstruction* object) { | 8474 HInstruction* object) { |
| 8465 ASSERT(boilerplate_object->properties()->length() == 0); | 8475 ASSERT(boilerplate_object->properties()->length() == 0); |
| 8466 | 8476 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8498 Handle<Object>(boilerplate_object->elements(), isolate()); | 8508 Handle<Object>(boilerplate_object->elements(), isolate()); |
| 8499 object_elements = Add<HConstant>(elements_field); | 8509 object_elements = Add<HConstant>(elements_field); |
| 8500 } | 8510 } |
| 8501 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 8511 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 8502 object_elements); | 8512 object_elements); |
| 8503 } | 8513 } |
| 8504 | 8514 |
| 8505 | 8515 |
| 8506 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( | 8516 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
| 8507 Handle<JSObject> boilerplate_object, | 8517 Handle<JSObject> boilerplate_object, |
| 8508 HInstruction* object) { | 8518 HInstruction* object, |
| 8519 AllocationSiteContext* site_context) { |
| 8509 Handle<DescriptorArray> descriptors( | 8520 Handle<DescriptorArray> descriptors( |
| 8510 boilerplate_object->map()->instance_descriptors()); | 8521 boilerplate_object->map()->instance_descriptors()); |
| 8511 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); | 8522 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| 8512 | 8523 |
| 8513 int copied_fields = 0; | 8524 int copied_fields = 0; |
| 8514 for (int i = 0; i < limit; i++) { | 8525 for (int i = 0; i < limit; i++) { |
| 8515 PropertyDetails details = descriptors->GetDetails(i); | 8526 PropertyDetails details = descriptors->GetDetails(i); |
| 8516 if (details.type() != FIELD) continue; | 8527 if (details.type() != FIELD) continue; |
| 8517 copied_fields++; | 8528 copied_fields++; |
| 8518 int index = descriptors->GetFieldIndex(i); | 8529 int index = descriptors->GetFieldIndex(i); |
| 8519 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); | 8530 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
| 8520 Handle<Name> name(descriptors->GetKey(i)); | 8531 Handle<Name> name(descriptors->GetKey(i)); |
| 8521 Handle<Object> value = | 8532 Handle<Object> value = |
| 8522 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), | 8533 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
| 8523 isolate()); | 8534 isolate()); |
| 8524 | 8535 |
| 8525 // The access for the store depends on the type of the boilerplate. | 8536 // The access for the store depends on the type of the boilerplate. |
| 8526 HObjectAccess access = boilerplate_object->IsJSArray() ? | 8537 HObjectAccess access = boilerplate_object->IsJSArray() ? |
| 8527 HObjectAccess::ForJSArrayOffset(property_offset) : | 8538 HObjectAccess::ForJSArrayOffset(property_offset) : |
| 8528 HObjectAccess::ForJSObjectOffset(property_offset); | 8539 HObjectAccess::ForJSObjectOffset(property_offset); |
| 8529 | 8540 |
| 8530 if (value->IsJSObject()) { | 8541 if (value->IsJSObject()) { |
| 8542 AllocationSiteUsageScope site_scope(site_context, value); |
| 8531 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 8543 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 8532 HInstruction* result = BuildFastLiteral(value_object); | 8544 HInstruction* result = |
| 8545 BuildFastLiteral(value_object, site_context); |
| 8533 Add<HStoreNamedField>(object, access, result); | 8546 Add<HStoreNamedField>(object, access, result); |
| 8534 } else { | 8547 } else { |
| 8535 Representation representation = details.representation(); | 8548 Representation representation = details.representation(); |
| 8536 HInstruction* value_instruction = Add<HConstant>(value); | 8549 HInstruction* value_instruction = Add<HConstant>(value); |
| 8537 | 8550 |
| 8538 if (representation.IsDouble()) { | 8551 if (representation.IsDouble()) { |
| 8539 // Allocate a HeapNumber box and store the value into it. | 8552 // Allocate a HeapNumber box and store the value into it. |
| 8540 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); | 8553 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); |
| 8554 // TODO(mvstanton): This heap number alloc does not have a corresponding |
| 8555 // AllocationSite. That is okay because |
| 8556 // 1) it's a child object of another object with a valid allocation site |
| 8557 // 2) we can just use the mode of the parent object for pretenuring |
| 8558 // The todo is replace GetPretenureMode() with |
| 8559 // site_context->top()->GetPretenureMode(). |
| 8541 HInstruction* double_box = | 8560 HInstruction* double_box = |
| 8542 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), | 8561 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), |
| 8543 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE); | 8562 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE); |
| 8544 AddStoreMapConstant(double_box, | 8563 AddStoreMapConstant(double_box, |
| 8545 isolate()->factory()->heap_number_map()); | 8564 isolate()->factory()->heap_number_map()); |
| 8546 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), | 8565 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), |
| 8547 value_instruction); | 8566 value_instruction); |
| 8548 value_instruction = double_box; | 8567 value_instruction = double_box; |
| 8549 } | 8568 } |
| 8550 | 8569 |
| 8551 Add<HStoreNamedField>(object, access, value_instruction); | 8570 Add<HStoreNamedField>(object, access, value_instruction); |
| 8552 } | 8571 } |
| 8553 } | 8572 } |
| 8554 | 8573 |
| 8555 int inobject_properties = boilerplate_object->map()->inobject_properties(); | 8574 int inobject_properties = boilerplate_object->map()->inobject_properties(); |
| 8556 HInstruction* value_instruction = | 8575 HInstruction* value_instruction = |
| 8557 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); | 8576 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); |
| 8558 for (int i = copied_fields; i < inobject_properties; i++) { | 8577 for (int i = copied_fields; i < inobject_properties; i++) { |
| 8559 ASSERT(boilerplate_object->IsJSObject()); | 8578 ASSERT(boilerplate_object->IsJSObject()); |
| 8560 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); | 8579 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); |
| 8561 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); | 8580 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); |
| 8562 Add<HStoreNamedField>(object, access, value_instruction); | 8581 Add<HStoreNamedField>(object, access, value_instruction); |
| 8563 } | 8582 } |
| 8564 } | 8583 } |
| 8565 | 8584 |
| 8566 | 8585 |
| 8567 void HOptimizedGraphBuilder::BuildEmitElements( | 8586 void HOptimizedGraphBuilder::BuildEmitElements( |
| 8568 Handle<JSObject> boilerplate_object, | 8587 Handle<JSObject> boilerplate_object, |
| 8569 Handle<FixedArrayBase> elements, | 8588 Handle<FixedArrayBase> elements, |
| 8570 HValue* object_elements) { | 8589 HValue* object_elements, |
| 8590 AllocationSiteContext* site_context) { |
| 8571 ElementsKind kind = boilerplate_object->map()->elements_kind(); | 8591 ElementsKind kind = boilerplate_object->map()->elements_kind(); |
| 8572 int elements_length = elements->length(); | 8592 int elements_length = elements->length(); |
| 8573 HValue* object_elements_length = Add<HConstant>(elements_length); | 8593 HValue* object_elements_length = Add<HConstant>(elements_length); |
| 8574 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); | 8594 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); |
| 8575 | 8595 |
| 8576 // Copy elements backing store content. | 8596 // Copy elements backing store content. |
| 8577 if (elements->IsFixedDoubleArray()) { | 8597 if (elements->IsFixedDoubleArray()) { |
| 8578 BuildEmitFixedDoubleArray(elements, kind, object_elements); | 8598 BuildEmitFixedDoubleArray(elements, kind, object_elements); |
| 8579 } else if (elements->IsFixedArray()) { | 8599 } else if (elements->IsFixedArray()) { |
| 8580 BuildEmitFixedArray(elements, kind, object_elements); | 8600 BuildEmitFixedArray(elements, kind, object_elements, |
| 8601 site_context); |
| 8581 } else { | 8602 } else { |
| 8582 UNREACHABLE(); | 8603 UNREACHABLE(); |
| 8583 } | 8604 } |
| 8584 } | 8605 } |
| 8585 | 8606 |
| 8586 | 8607 |
| 8587 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 8608 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
| 8588 Handle<FixedArrayBase> elements, | 8609 Handle<FixedArrayBase> elements, |
| 8589 ElementsKind kind, | 8610 ElementsKind kind, |
| 8590 HValue* object_elements) { | 8611 HValue* object_elements) { |
| 8591 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 8612 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 8592 int elements_length = elements->length(); | 8613 int elements_length = elements->length(); |
| 8593 for (int i = 0; i < elements_length; i++) { | 8614 for (int i = 0; i < elements_length; i++) { |
| 8594 HValue* key_constant = Add<HConstant>(i); | 8615 HValue* key_constant = Add<HConstant>(i); |
| 8595 HInstruction* value_instruction = | 8616 HInstruction* value_instruction = |
| 8596 Add<HLoadKeyed>(boilerplate_elements, key_constant, | 8617 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
| 8597 static_cast<HValue*>(NULL), kind, | 8618 static_cast<HValue*>(NULL), kind, |
| 8598 ALLOW_RETURN_HOLE); | 8619 ALLOW_RETURN_HOLE); |
| 8599 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, | 8620 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, |
| 8600 value_instruction, kind); | 8621 value_instruction, kind); |
| 8601 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 8622 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 8602 } | 8623 } |
| 8603 } | 8624 } |
| 8604 | 8625 |
| 8605 | 8626 |
| 8606 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 8627 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
| 8607 Handle<FixedArrayBase> elements, | 8628 Handle<FixedArrayBase> elements, |
| 8608 ElementsKind kind, | 8629 ElementsKind kind, |
| 8609 HValue* object_elements) { | 8630 HValue* object_elements, |
| 8631 AllocationSiteContext* site_context) { |
| 8610 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 8632 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 8611 int elements_length = elements->length(); | 8633 int elements_length = elements->length(); |
| 8612 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 8634 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 8613 for (int i = 0; i < elements_length; i++) { | 8635 for (int i = 0; i < elements_length; i++) { |
| 8614 Handle<Object> value(fast_elements->get(i), isolate()); | 8636 Handle<Object> value(fast_elements->get(i), isolate()); |
| 8615 HValue* key_constant = Add<HConstant>(i); | 8637 HValue* key_constant = Add<HConstant>(i); |
| 8616 if (value->IsJSObject()) { | 8638 if (value->IsJSObject()) { |
| 8639 AllocationSiteUsageScope site_scope(site_context, value); |
| 8617 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 8640 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 8618 HInstruction* result = BuildFastLiteral(value_object); | 8641 HInstruction* result = |
| 8642 BuildFastLiteral(value_object, site_context); |
| 8619 Add<HStoreKeyed>(object_elements, key_constant, result, kind); | 8643 Add<HStoreKeyed>(object_elements, key_constant, result, kind); |
| 8620 } else { | 8644 } else { |
| 8621 HInstruction* value_instruction = | 8645 HInstruction* value_instruction = |
| 8622 Add<HLoadKeyed>(boilerplate_elements, key_constant, | 8646 Add<HLoadKeyed>(boilerplate_elements, key_constant, |
| 8623 static_cast<HValue*>(NULL), kind, | 8647 static_cast<HValue*>(NULL), kind, |
| 8624 ALLOW_RETURN_HOLE); | 8648 ALLOW_RETURN_HOLE); |
| 8625 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); | 8649 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); |
| 8626 } | 8650 } |
| 8627 } | 8651 } |
| 8628 } | 8652 } |
| (...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9880 if (ShouldProduceTraceOutput()) { | 9904 if (ShouldProduceTraceOutput()) { |
| 9881 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9905 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9882 } | 9906 } |
| 9883 | 9907 |
| 9884 #ifdef DEBUG | 9908 #ifdef DEBUG |
| 9885 graph_->Verify(false); // No full verify. | 9909 graph_->Verify(false); // No full verify. |
| 9886 #endif | 9910 #endif |
| 9887 } | 9911 } |
| 9888 | 9912 |
| 9889 } } // namespace v8::internal | 9913 } } // namespace v8::internal |
| OLD | NEW |