| 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 |