| 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 2224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2235 | 2235 |
| 2236 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); | 2236 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
| 2237 Add<HStoreNamedField>(array, access, empty_fixed_array); | 2237 Add<HStoreNamedField>(array, access, empty_fixed_array); |
| 2238 Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind), | 2238 Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind), |
| 2239 length_field); | 2239 length_field); |
| 2240 | 2240 |
| 2241 if (mode == TRACK_ALLOCATION_SITE) { | 2241 if (mode == TRACK_ALLOCATION_SITE) { |
| 2242 BuildCreateAllocationMemento(array, | 2242 BuildCreateAllocationMemento(array, |
| 2243 JSArray::kSize, | 2243 JSArray::kSize, |
| 2244 allocation_site_payload); | 2244 allocation_site_payload); |
| 2245 if (FLAG_allocation_site_pretenuring) { |
| 2246 // TODO(mvstanton): move this code into BuildCreateAllocationMemento when |
| 2247 // constructed arrays also pay attention to pretenuring. |
| 2248 HObjectAccess access = |
| 2249 HObjectAccess::ForAllocationSiteOffset( |
| 2250 AllocationSite::kMementoCreateCountOffset); |
| 2251 HValue* create_info = Add<HLoadNamedField>(allocation_site_payload, |
| 2252 access); |
| 2253 HInstruction* new_create_info = |
| 2254 AddUncasted<HAdd>(create_info, graph()->GetConstant1()); |
| 2255 new_create_info->ClearFlag(HValue::kCanOverflow); |
| 2256 HStoreNamedField* store = Add<HStoreNamedField>(allocation_site_payload, |
| 2257 access, new_create_info); |
| 2258 // No write barrier needed to store a smi. |
| 2259 store->SkipWriteBarrier(); |
| 2260 } |
| 2245 } | 2261 } |
| 2246 | 2262 |
| 2247 int elements_location = JSArray::kSize; | 2263 int elements_location = JSArray::kSize; |
| 2248 if (mode == TRACK_ALLOCATION_SITE) { | 2264 if (mode == TRACK_ALLOCATION_SITE) { |
| 2249 elements_location += AllocationMemento::kSize; | 2265 elements_location += AllocationMemento::kSize; |
| 2250 } | 2266 } |
| 2251 | 2267 |
| 2252 HValue* elements = Add<HInnerAllocatedObject>(array, elements_location); | 2268 HValue* elements = Add<HInnerAllocatedObject>(array, elements_location); |
| 2253 Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements); | 2269 Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements); |
| 2254 return static_cast<HInnerAllocatedObject*>(elements); | 2270 return static_cast<HInnerAllocatedObject*>(elements); |
| (...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3749 Run<HRedundantPhiEliminationPhase>(); | 3765 Run<HRedundantPhiEliminationPhase>(); |
| 3750 if (!CheckArgumentsPhiUses()) { | 3766 if (!CheckArgumentsPhiUses()) { |
| 3751 *bailout_reason = kUnsupportedPhiUseOfArguments; | 3767 *bailout_reason = kUnsupportedPhiUseOfArguments; |
| 3752 return false; | 3768 return false; |
| 3753 } | 3769 } |
| 3754 | 3770 |
| 3755 // Find and mark unreachable code to simplify optimizations, especially gvn, | 3771 // Find and mark unreachable code to simplify optimizations, especially gvn, |
| 3756 // where unreachable code could unnecessarily defeat LICM. | 3772 // where unreachable code could unnecessarily defeat LICM. |
| 3757 Run<HMarkUnreachableBlocksPhase>(); | 3773 Run<HMarkUnreachableBlocksPhase>(); |
| 3758 | 3774 |
| 3759 if (FLAG_check_elimination) Run<HCheckEliminationPhase>(); | |
| 3760 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); | 3775 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); |
| 3761 if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>(); | 3776 if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>(); |
| 3762 | 3777 |
| 3763 if (FLAG_load_elimination) Run<HLoadEliminationPhase>(); | 3778 if (FLAG_load_elimination) Run<HLoadEliminationPhase>(); |
| 3764 | 3779 |
| 3765 CollectPhis(); | 3780 CollectPhis(); |
| 3766 | 3781 |
| 3767 if (has_osr()) osr()->FinishOsrValues(); | 3782 if (has_osr()) osr()->FinishOsrValues(); |
| 3768 | 3783 |
| 3769 Run<HInferRepresentationPhase>(); | 3784 Run<HInferRepresentationPhase>(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3780 | 3795 |
| 3781 // Must be performed before canonicalization to ensure that Canonicalize | 3796 // Must be performed before canonicalization to ensure that Canonicalize |
| 3782 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with | 3797 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with |
| 3783 // zero. | 3798 // zero. |
| 3784 if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>(); | 3799 if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>(); |
| 3785 | 3800 |
| 3786 if (FLAG_use_canonicalizing) Run<HCanonicalizePhase>(); | 3801 if (FLAG_use_canonicalizing) Run<HCanonicalizePhase>(); |
| 3787 | 3802 |
| 3788 if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>(); | 3803 if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>(); |
| 3789 | 3804 |
| 3805 if (FLAG_check_elimination) Run<HCheckEliminationPhase>(); |
| 3806 |
| 3790 if (FLAG_use_range) Run<HRangeAnalysisPhase>(); | 3807 if (FLAG_use_range) Run<HRangeAnalysisPhase>(); |
| 3791 | 3808 |
| 3792 Run<HComputeChangeUndefinedToNaN>(); | 3809 Run<HComputeChangeUndefinedToNaN>(); |
| 3793 Run<HComputeMinusZeroChecksPhase>(); | 3810 Run<HComputeMinusZeroChecksPhase>(); |
| 3794 | 3811 |
| 3795 // Eliminate redundant stack checks on backwards branches. | 3812 // Eliminate redundant stack checks on backwards branches. |
| 3796 Run<HStackCheckEliminationPhase>(); | 3813 Run<HStackCheckEliminationPhase>(); |
| 3797 | 3814 |
| 3798 if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>(); | 3815 if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>(); |
| 3799 if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>(); | 3816 if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>(); |
| (...skipping 3755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7555 if (args->length() != 2) return false; | 7572 if (args->length() != 2) return false; |
| 7556 | 7573 |
| 7557 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); | 7574 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); |
| 7558 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; | 7575 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; |
| 7559 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); | 7576 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); |
| 7560 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; | 7577 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; |
| 7561 | 7578 |
| 7562 // Found pattern f.apply(receiver, arguments). | 7579 // Found pattern f.apply(receiver, arguments). |
| 7563 CHECK_ALIVE_OR_RETURN(VisitForValue(prop->obj()), true); | 7580 CHECK_ALIVE_OR_RETURN(VisitForValue(prop->obj()), true); |
| 7564 HValue* function = Top(); | 7581 HValue* function = Top(); |
| 7582 // The function get here may be an undefined constant if lookup fails. |
| 7583 if (function->IsConstant() && |
| 7584 !HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 7585 Drop(1); |
| 7586 return false; |
| 7587 } |
| 7588 |
| 7565 AddCheckConstantFunction(expr->holder(), function, function_map); | 7589 AddCheckConstantFunction(expr->holder(), function, function_map); |
| 7566 Drop(1); | 7590 Drop(1); |
| 7567 | 7591 |
| 7568 CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true); | 7592 CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true); |
| 7569 HValue* receiver = Pop(); | 7593 HValue* receiver = Pop(); |
| 7570 | 7594 |
| 7571 if (function_state()->outer() == NULL) { | 7595 if (function_state()->outer() == NULL) { |
| 7572 HInstruction* elements = Add<HArgumentsElements>(false); | 7596 HInstruction* elements = Add<HArgumentsElements>(false); |
| 7573 HInstruction* length = Add<HArgumentsLength>(elements); | 7597 HInstruction* length = Add<HArgumentsLength>(elements); |
| 7574 HValue* wrapped_receiver = BuildWrapReceiver(receiver, function); | 7598 HValue* wrapped_receiver = BuildWrapReceiver(receiver, function); |
| (...skipping 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9344 Handle<JSObject> boilerplate_object, | 9368 Handle<JSObject> boilerplate_object, |
| 9345 AllocationSiteUsageContext* site_context) { | 9369 AllocationSiteUsageContext* site_context) { |
| 9346 NoObservableSideEffectsScope no_effects(this); | 9370 NoObservableSideEffectsScope no_effects(this); |
| 9347 InstanceType instance_type = boilerplate_object->map()->instance_type(); | 9371 InstanceType instance_type = boilerplate_object->map()->instance_type(); |
| 9348 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); | 9372 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); |
| 9349 | 9373 |
| 9350 HType type = instance_type == JS_ARRAY_TYPE | 9374 HType type = instance_type == JS_ARRAY_TYPE |
| 9351 ? HType::JSArray() : HType::JSObject(); | 9375 ? HType::JSArray() : HType::JSObject(); |
| 9352 HValue* object_size_constant = Add<HConstant>( | 9376 HValue* object_size_constant = Add<HConstant>( |
| 9353 boilerplate_object->map()->instance_size()); | 9377 boilerplate_object->map()->instance_size()); |
| 9378 |
| 9379 // We should pull pre-tenure mode from the allocation site. |
| 9380 // For now, just see what it says, and remark on it if it sez |
| 9381 // we should pretenure. That means the rudimentary counting in the garbage |
| 9382 // collector is having an effect. |
| 9383 PretenureFlag pretenure_flag = isolate()->heap()->GetPretenureMode(); |
| 9384 if (FLAG_allocation_site_pretenuring) { |
| 9385 pretenure_flag = site_context->current()->GetPretenureMode() |
| 9386 ? TENURED |
| 9387 : NOT_TENURED; |
| 9388 } |
| 9389 |
| 9354 HInstruction* object = Add<HAllocate>(object_size_constant, type, | 9390 HInstruction* object = Add<HAllocate>(object_size_constant, type, |
| 9355 isolate()->heap()->GetPretenureMode(), instance_type); | 9391 pretenure_flag, instance_type, site_context->current()); |
| 9356 | 9392 |
| 9357 BuildEmitObjectHeader(boilerplate_object, object); | 9393 BuildEmitObjectHeader(boilerplate_object, object); |
| 9358 | 9394 |
| 9359 Handle<FixedArrayBase> elements(boilerplate_object->elements()); | 9395 Handle<FixedArrayBase> elements(boilerplate_object->elements()); |
| 9360 int elements_size = (elements->length() > 0 && | 9396 int elements_size = (elements->length() > 0 && |
| 9361 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? | 9397 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? |
| 9362 elements->Size() : 0; | 9398 elements->Size() : 0; |
| 9363 | 9399 |
| 9364 HInstruction* object_elements = NULL; | 9400 HInstruction* object_elements = NULL; |
| 9365 if (elements_size > 0) { | 9401 if (elements_size > 0) { |
| 9366 HValue* object_elements_size = Add<HConstant>(elements_size); | 9402 HValue* object_elements_size = Add<HConstant>(elements_size); |
| 9367 if (boilerplate_object->HasFastDoubleElements()) { | 9403 if (boilerplate_object->HasFastDoubleElements()) { |
| 9368 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 9404 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
| 9369 isolate()->heap()->GetPretenureMode(), FIXED_DOUBLE_ARRAY_TYPE); | 9405 pretenure_flag, FIXED_DOUBLE_ARRAY_TYPE, site_context->current()); |
| 9370 } else { | 9406 } else { |
| 9371 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), | 9407 object_elements = Add<HAllocate>(object_elements_size, HType::JSObject(), |
| 9372 isolate()->heap()->GetPretenureMode(), FIXED_ARRAY_TYPE); | 9408 pretenure_flag, FIXED_ARRAY_TYPE, site_context->current()); |
| 9373 } | 9409 } |
| 9374 } | 9410 } |
| 9375 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); | 9411 BuildInitElementsInObjectHeader(boilerplate_object, object, object_elements); |
| 9376 | 9412 |
| 9377 // Copy object elements if non-COW. | 9413 // Copy object elements if non-COW. |
| 9378 if (object_elements != NULL) { | 9414 if (object_elements != NULL) { |
| 9379 BuildEmitElements(boilerplate_object, elements, object_elements, | 9415 BuildEmitElements(boilerplate_object, elements, object_elements, |
| 9380 site_context); | 9416 site_context); |
| 9381 } | 9417 } |
| 9382 | 9418 |
| 9383 // Copy in-object properties. | 9419 // Copy in-object properties. |
| 9384 if (boilerplate_object->map()->NumberOfFields() != 0) { | 9420 if (boilerplate_object->map()->NumberOfFields() != 0) { |
| 9385 BuildEmitInObjectProperties(boilerplate_object, object, site_context); | 9421 BuildEmitInObjectProperties(boilerplate_object, object, site_context, |
| 9422 pretenure_flag); |
| 9386 } | 9423 } |
| 9387 return object; | 9424 return object; |
| 9388 } | 9425 } |
| 9389 | 9426 |
| 9390 | 9427 |
| 9391 void HOptimizedGraphBuilder::BuildEmitObjectHeader( | 9428 void HOptimizedGraphBuilder::BuildEmitObjectHeader( |
| 9392 Handle<JSObject> boilerplate_object, | 9429 Handle<JSObject> boilerplate_object, |
| 9393 HInstruction* object) { | 9430 HInstruction* object) { |
| 9394 ASSERT(boilerplate_object->properties()->length() == 0); | 9431 ASSERT(boilerplate_object->properties()->length() == 0); |
| 9395 | 9432 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9428 object_elements = Add<HConstant>(elements_field); | 9465 object_elements = Add<HConstant>(elements_field); |
| 9429 } | 9466 } |
| 9430 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 9467 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 9431 object_elements); | 9468 object_elements); |
| 9432 } | 9469 } |
| 9433 | 9470 |
| 9434 | 9471 |
| 9435 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( | 9472 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
| 9436 Handle<JSObject> boilerplate_object, | 9473 Handle<JSObject> boilerplate_object, |
| 9437 HInstruction* object, | 9474 HInstruction* object, |
| 9438 AllocationSiteUsageContext* site_context) { | 9475 AllocationSiteUsageContext* site_context, |
| 9476 PretenureFlag pretenure_flag) { |
| 9439 Handle<DescriptorArray> descriptors( | 9477 Handle<DescriptorArray> descriptors( |
| 9440 boilerplate_object->map()->instance_descriptors()); | 9478 boilerplate_object->map()->instance_descriptors()); |
| 9441 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); | 9479 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| 9442 | 9480 |
| 9443 int copied_fields = 0; | 9481 int copied_fields = 0; |
| 9444 for (int i = 0; i < limit; i++) { | 9482 for (int i = 0; i < limit; i++) { |
| 9445 PropertyDetails details = descriptors->GetDetails(i); | 9483 PropertyDetails details = descriptors->GetDetails(i); |
| 9446 if (details.type() != FIELD) continue; | 9484 if (details.type() != FIELD) continue; |
| 9447 copied_fields++; | 9485 copied_fields++; |
| 9448 int index = descriptors->GetFieldIndex(i); | 9486 int index = descriptors->GetFieldIndex(i); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 9464 BuildFastLiteral(value_object, site_context); | 9502 BuildFastLiteral(value_object, site_context); |
| 9465 site_context->ExitScope(current_site, value_object); | 9503 site_context->ExitScope(current_site, value_object); |
| 9466 Add<HStoreNamedField>(object, access, result); | 9504 Add<HStoreNamedField>(object, access, result); |
| 9467 } else { | 9505 } else { |
| 9468 Representation representation = details.representation(); | 9506 Representation representation = details.representation(); |
| 9469 HInstruction* value_instruction = Add<HConstant>(value); | 9507 HInstruction* value_instruction = Add<HConstant>(value); |
| 9470 | 9508 |
| 9471 if (representation.IsDouble()) { | 9509 if (representation.IsDouble()) { |
| 9472 // Allocate a HeapNumber box and store the value into it. | 9510 // Allocate a HeapNumber box and store the value into it. |
| 9473 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); | 9511 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); |
| 9474 // TODO(mvstanton): This heap number alloc does not have a corresponding | 9512 // This heap number alloc does not have a corresponding |
| 9475 // AllocationSite. That is okay because | 9513 // AllocationSite. That is okay because |
| 9476 // 1) it's a child object of another object with a valid allocation site | 9514 // 1) it's a child object of another object with a valid allocation site |
| 9477 // 2) we can just use the mode of the parent object for pretenuring | 9515 // 2) we can just use the mode of the parent object for pretenuring |
| 9478 // The todo is replace GetPretenureMode() with | |
| 9479 // site_context->top()->GetPretenureMode(). | |
| 9480 HInstruction* double_box = | 9516 HInstruction* double_box = |
| 9481 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), | 9517 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), |
| 9482 isolate()->heap()->GetPretenureMode(), HEAP_NUMBER_TYPE); | 9518 pretenure_flag, HEAP_NUMBER_TYPE); |
| 9483 AddStoreMapConstant(double_box, | 9519 AddStoreMapConstant(double_box, |
| 9484 isolate()->factory()->heap_number_map()); | 9520 isolate()->factory()->heap_number_map()); |
| 9485 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), | 9521 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), |
| 9486 value_instruction); | 9522 value_instruction); |
| 9487 value_instruction = double_box; | 9523 value_instruction = double_box; |
| 9488 } | 9524 } |
| 9489 | 9525 |
| 9490 Add<HStoreNamedField>(object, access, value_instruction); | 9526 Add<HStoreNamedField>(object, access, value_instruction); |
| 9491 } | 9527 } |
| 9492 } | 9528 } |
| (...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10804 if (ShouldProduceTraceOutput()) { | 10840 if (ShouldProduceTraceOutput()) { |
| 10805 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10841 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 10806 } | 10842 } |
| 10807 | 10843 |
| 10808 #ifdef DEBUG | 10844 #ifdef DEBUG |
| 10809 graph_->Verify(false); // No full verify. | 10845 graph_->Verify(false); // No full verify. |
| 10810 #endif | 10846 #endif |
| 10811 } | 10847 } |
| 10812 | 10848 |
| 10813 } } // namespace v8::internal | 10849 } } // namespace v8::internal |
| OLD | NEW |