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