Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: src/hydrogen.cc

Issue 143633007: A64: Synchronize with r18764. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1541 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 1552
1553 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); 1553 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1());
1554 mask->ChangeRepresentation(Representation::Integer32()); 1554 mask->ChangeRepresentation(Representation::Integer32());
1555 mask->ClearFlag(HValue::kCanOverflow); 1555 mask->ClearFlag(HValue::kCanOverflow);
1556 1556
1557 return BuildUncheckedDictionaryElementLoadHelper(elements, key, 1557 return BuildUncheckedDictionaryElementLoadHelper(elements, key,
1558 hash, mask, 0); 1558 hash, mask, 0);
1559 } 1559 }
1560 1560
1561 1561
1562 HValue* HGraphBuilder::BuildNumberToString(HValue* object, 1562 HValue* HGraphBuilder::BuildNumberToString(HValue* object, Type* type) {
1563 Handle<Type> type) {
1564 NoObservableSideEffectsScope scope(this); 1563 NoObservableSideEffectsScope scope(this);
1565 1564
1566 // Convert constant numbers at compile time. 1565 // Convert constant numbers at compile time.
1567 if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) { 1566 if (object->IsConstant() && HConstant::cast(object)->HasNumberValue()) {
1568 Handle<Object> number = HConstant::cast(object)->handle(isolate()); 1567 Handle<Object> number = HConstant::cast(object)->handle(isolate());
1569 Handle<String> result = isolate()->factory()->NumberToString(number); 1568 Handle<String> result = isolate()->factory()->NumberToString(number);
1570 return Add<HConstant>(result); 1569 return Add<HConstant>(result);
1571 } 1570 }
1572 1571
1573 // Create a joinable continuation. 1572 // Create a joinable continuation.
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 2072
2074 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 2073 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
2075 HValue* checked_object, 2074 HValue* checked_object,
2076 HValue* key, 2075 HValue* key,
2077 HValue* val, 2076 HValue* val,
2078 bool is_js_array, 2077 bool is_js_array,
2079 ElementsKind elements_kind, 2078 ElementsKind elements_kind,
2080 bool is_store, 2079 bool is_store,
2081 LoadKeyedHoleMode load_mode, 2080 LoadKeyedHoleMode load_mode,
2082 KeyedAccessStoreMode store_mode) { 2081 KeyedAccessStoreMode store_mode) {
2083 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); 2082 ASSERT((!IsExternalArrayElementsKind(elements_kind) &&
2083 !IsFixedTypedArrayElementsKind(elements_kind)) ||
2084 !is_js_array);
2084 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 2085 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency
2085 // on a HElementsTransition instruction. The flag can also be removed if the 2086 // on a HElementsTransition instruction. The flag can also be removed if the
2086 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 2087 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
2087 // ElementsKind transitions. Finally, the dependency can be removed for stores 2088 // ElementsKind transitions. Finally, the dependency can be removed for stores
2088 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 2089 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
2089 // generated store code. 2090 // generated store code.
2090 if ((elements_kind == FAST_HOLEY_ELEMENTS) || 2091 if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
2091 (elements_kind == FAST_ELEMENTS && is_store)) { 2092 (elements_kind == FAST_ELEMENTS && is_store)) {
2092 checked_object->ClearGVNFlag(kDependsOnElementsKind); 2093 checked_object->ClearGVNFlag(kDependsOnElementsKind);
2093 } 2094 }
2094 2095
2095 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); 2096 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
2096 bool fast_elements = IsFastObjectElementsKind(elements_kind); 2097 bool fast_elements = IsFastObjectElementsKind(elements_kind);
2097 HValue* elements = AddLoadElements(checked_object); 2098 HValue* elements = AddLoadElements(checked_object);
2098 if (is_store && (fast_elements || fast_smi_only_elements) && 2099 if (is_store && (fast_elements || fast_smi_only_elements) &&
2099 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 2100 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
2100 HCheckMaps* check_cow_map = Add<HCheckMaps>( 2101 HCheckMaps* check_cow_map = Add<HCheckMaps>(
2101 elements, isolate()->factory()->fixed_array_map(), top_info()); 2102 elements, isolate()->factory()->fixed_array_map(), top_info());
2102 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 2103 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
2103 } 2104 }
2104 HInstruction* length = NULL; 2105 HInstruction* length = NULL;
2105 if (is_js_array) { 2106 if (is_js_array) {
2106 length = Add<HLoadNamedField>( 2107 length = Add<HLoadNamedField>(
2107 checked_object, HObjectAccess::ForArrayLength(elements_kind)); 2108 checked_object, HObjectAccess::ForArrayLength(elements_kind));
2108 } else { 2109 } else {
2109 length = AddLoadFixedArrayLength(elements); 2110 length = AddLoadFixedArrayLength(elements);
2110 } 2111 }
2111 length->set_type(HType::Smi()); 2112 length->set_type(HType::Smi());
2112 HValue* checked_key = NULL; 2113 HValue* checked_key = NULL;
2113 if (IsExternalArrayElementsKind(elements_kind)) { 2114 if (IsExternalArrayElementsKind(elements_kind) ||
2115 IsFixedTypedArrayElementsKind(elements_kind)) {
2116 HValue* backing_store;
2117 if (IsExternalArrayElementsKind(elements_kind)) {
2118 backing_store =
2119 Add<HLoadExternalArrayPointer>(elements);
2120 } else {
2121 backing_store = elements;
2122 }
2114 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 2123 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
2115 NoObservableSideEffectsScope no_effects(this); 2124 NoObservableSideEffectsScope no_effects(this);
2116 HLoadExternalArrayPointer* external_elements =
2117 Add<HLoadExternalArrayPointer>(elements);
2118 IfBuilder length_checker(this); 2125 IfBuilder length_checker(this);
2119 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 2126 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
2120 length_checker.Then(); 2127 length_checker.Then();
2121 IfBuilder negative_checker(this); 2128 IfBuilder negative_checker(this);
2122 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 2129 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
2123 key, graph()->GetConstant0(), Token::GTE); 2130 key, graph()->GetConstant0(), Token::GTE);
2124 negative_checker.Then(); 2131 negative_checker.Then();
2125 HInstruction* result = AddElementAccess( 2132 HInstruction* result = AddElementAccess(
2126 external_elements, key, val, bounds_check, elements_kind, is_store); 2133 backing_store, key, val, bounds_check, elements_kind, is_store);
2127 negative_checker.ElseDeopt("Negative key encountered"); 2134 negative_checker.ElseDeopt("Negative key encountered");
2128 negative_checker.End(); 2135 negative_checker.End();
2129 length_checker.End(); 2136 length_checker.End();
2130 return result; 2137 return result;
2131 } else { 2138 } else {
2132 ASSERT(store_mode == STANDARD_STORE); 2139 ASSERT(store_mode == STANDARD_STORE);
2133 checked_key = Add<HBoundsCheck>(key, length); 2140 checked_key = Add<HBoundsCheck>(key, length);
2134 HLoadExternalArrayPointer* external_elements =
2135 Add<HLoadExternalArrayPointer>(elements);
2136 return AddElementAccess( 2141 return AddElementAccess(
2137 external_elements, checked_key, val, 2142 backing_store, checked_key, val,
2138 checked_object, elements_kind, is_store); 2143 checked_object, elements_kind, is_store);
2139 } 2144 }
2140 } 2145 }
2141 ASSERT(fast_smi_only_elements || 2146 ASSERT(fast_smi_only_elements ||
2142 fast_elements || 2147 fast_elements ||
2143 IsFastDoubleElementsKind(elements_kind)); 2148 IsFastDoubleElementsKind(elements_kind));
2144 2149
2145 // In case val is stored into a fast smi array, assure that the value is a smi 2150 // In case val is stored into a fast smi array, assure that the value is a smi
2146 // before manipulating the backing store. Otherwise the actual store may 2151 // before manipulating the backing store. Otherwise the actual store may
2147 // deopt, leaving the backing store in an invalid state. 2152 // deopt, leaving the backing store in an invalid state.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 HInstruction* HGraphBuilder::AddElementAccess( 2313 HInstruction* HGraphBuilder::AddElementAccess(
2309 HValue* elements, 2314 HValue* elements,
2310 HValue* checked_key, 2315 HValue* checked_key,
2311 HValue* val, 2316 HValue* val,
2312 HValue* dependency, 2317 HValue* dependency,
2313 ElementsKind elements_kind, 2318 ElementsKind elements_kind,
2314 bool is_store, 2319 bool is_store,
2315 LoadKeyedHoleMode load_mode) { 2320 LoadKeyedHoleMode load_mode) {
2316 if (is_store) { 2321 if (is_store) {
2317 ASSERT(val != NULL); 2322 ASSERT(val != NULL);
2318 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { 2323 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
2324 elements_kind == UINT8_CLAMPED_ELEMENTS) {
2319 val = Add<HClampToUint8>(val); 2325 val = Add<HClampToUint8>(val);
2320 } 2326 }
2321 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, 2327 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind,
2322 elements_kind == FAST_SMI_ELEMENTS 2328 elements_kind == FAST_SMI_ELEMENTS
2323 ? STORE_TO_INITIALIZED_ENTRY 2329 ? STORE_TO_INITIALIZED_ENTRY
2324 : INITIALIZING_STORE); 2330 : INITIALIZING_STORE);
2325 } 2331 }
2326 2332
2327 ASSERT(!is_store); 2333 ASSERT(!is_store);
2328 ASSERT(val == NULL); 2334 ASSERT(val == NULL);
2329 HLoadKeyed* load = Add<HLoadKeyed>( 2335 HLoadKeyed* load = Add<HLoadKeyed>(
2330 elements, checked_key, dependency, elements_kind, load_mode); 2336 elements, checked_key, dependency, elements_kind, load_mode);
2331 if (FLAG_opt_safe_uint32_operations && 2337 if (FLAG_opt_safe_uint32_operations &&
2332 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { 2338 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS ||
2339 elements_kind == UINT32_ELEMENTS)) {
2333 graph()->RecordUint32Instruction(load); 2340 graph()->RecordUint32Instruction(load);
2334 } 2341 }
2335 return load; 2342 return load;
2336 } 2343 }
2337 2344
2338 2345
2339 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) { 2346 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) {
2340 return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer()); 2347 return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer());
2341 } 2348 }
2342 2349
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2571 Add<HStoreKeyed>(object_elements, key_constant, value, kind); 2578 Add<HStoreKeyed>(object_elements, key_constant, value, kind);
2572 } 2579 }
2573 } 2580 }
2574 2581
2575 return object; 2582 return object;
2576 } 2583 }
2577 2584
2578 2585
2579 void HGraphBuilder::BuildCompareNil( 2586 void HGraphBuilder::BuildCompareNil(
2580 HValue* value, 2587 HValue* value,
2581 Handle<Type> type, 2588 Type* type,
2582 HIfContinuation* continuation) { 2589 HIfContinuation* continuation) {
2583 IfBuilder if_nil(this); 2590 IfBuilder if_nil(this);
2584 bool some_case_handled = false; 2591 bool some_case_handled = false;
2585 bool some_case_missing = false; 2592 bool some_case_missing = false;
2586 2593
2587 if (type->Maybe(Type::Null())) { 2594 if (type->Maybe(Type::Null())) {
2588 if (some_case_handled) if_nil.Or(); 2595 if (some_case_handled) if_nil.Or();
2589 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); 2596 if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull());
2590 some_case_handled = true; 2597 some_case_handled = true;
2591 } else { 2598 } else {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2691 2698
2692 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 2699 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
2693 ElementsKind kind, 2700 ElementsKind kind,
2694 HValue* allocation_site_payload, 2701 HValue* allocation_site_payload,
2695 HValue* constructor_function, 2702 HValue* constructor_function,
2696 AllocationSiteOverrideMode override_mode) : 2703 AllocationSiteOverrideMode override_mode) :
2697 builder_(builder), 2704 builder_(builder),
2698 kind_(kind), 2705 kind_(kind),
2699 allocation_site_payload_(allocation_site_payload), 2706 allocation_site_payload_(allocation_site_payload),
2700 constructor_function_(constructor_function) { 2707 constructor_function_(constructor_function) {
2708 ASSERT(!allocation_site_payload->IsConstant() ||
2709 HConstant::cast(allocation_site_payload)->handle(
2710 builder_->isolate())->IsAllocationSite());
2701 mode_ = override_mode == DISABLE_ALLOCATION_SITES 2711 mode_ = override_mode == DISABLE_ALLOCATION_SITES
2702 ? DONT_TRACK_ALLOCATION_SITE 2712 ? DONT_TRACK_ALLOCATION_SITE
2703 : AllocationSite::GetMode(kind); 2713 : AllocationSite::GetMode(kind);
2704 } 2714 }
2705 2715
2706 2716
2707 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 2717 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
2708 ElementsKind kind, 2718 ElementsKind kind,
2709 HValue* constructor_function) : 2719 HValue* constructor_function) :
2710 builder_(builder), 2720 builder_(builder),
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
2886 ast_context_(NULL), 2896 ast_context_(NULL),
2887 break_scope_(NULL), 2897 break_scope_(NULL),
2888 inlined_count_(0), 2898 inlined_count_(0),
2889 globals_(10, info->zone()), 2899 globals_(10, info->zone()),
2890 inline_bailout_(false), 2900 inline_bailout_(false),
2891 osr_(new(info->zone()) HOsrBuilder(this)) { 2901 osr_(new(info->zone()) HOsrBuilder(this)) {
2892 // This is not initialized in the initializer list because the 2902 // This is not initialized in the initializer list because the
2893 // constructor for the initial state relies on function_state_ == NULL 2903 // constructor for the initial state relies on function_state_ == NULL
2894 // to know it's the initial state. 2904 // to know it's the initial state.
2895 function_state_= &initial_function_state_; 2905 function_state_= &initial_function_state_;
2896 InitializeAstVisitor(info->isolate()); 2906 InitializeAstVisitor(info->zone());
2897 if (FLAG_emit_opt_code_positions) { 2907 if (FLAG_emit_opt_code_positions) {
2898 SetSourcePosition(info->shared_info()->start_position()); 2908 SetSourcePosition(info->shared_info()->start_position());
2899 } 2909 }
2900 } 2910 }
2901 2911
2902 2912
2903 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, 2913 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first,
2904 HBasicBlock* second, 2914 HBasicBlock* second,
2905 BailoutId join_id) { 2915 BailoutId join_id) {
2906 if (first == NULL) { 2916 if (first == NULL) {
(...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after
4217 ZoneList<CaseClause*>* clauses = stmt->cases(); 4227 ZoneList<CaseClause*>* clauses = stmt->cases();
4218 int clause_count = clauses->length(); 4228 int clause_count = clauses->length();
4219 ZoneList<HBasicBlock*> body_blocks(clause_count, zone()); 4229 ZoneList<HBasicBlock*> body_blocks(clause_count, zone());
4220 if (clause_count > kCaseClauseLimit) { 4230 if (clause_count > kCaseClauseLimit) {
4221 return Bailout(kSwitchStatementTooManyClauses); 4231 return Bailout(kSwitchStatementTooManyClauses);
4222 } 4232 }
4223 4233
4224 CHECK_ALIVE(VisitForValue(stmt->tag())); 4234 CHECK_ALIVE(VisitForValue(stmt->tag()));
4225 Add<HSimulate>(stmt->EntryId()); 4235 Add<HSimulate>(stmt->EntryId());
4226 HValue* tag_value = Top(); 4236 HValue* tag_value = Top();
4227 Handle<Type> tag_type = stmt->tag()->bounds().lower; 4237 Type* tag_type = stmt->tag()->bounds().lower;
4228 4238
4229 // 1. Build all the tests, with dangling true branches 4239 // 1. Build all the tests, with dangling true branches
4230 BailoutId default_id = BailoutId::None(); 4240 BailoutId default_id = BailoutId::None();
4231 for (int i = 0; i < clause_count; ++i) { 4241 for (int i = 0; i < clause_count; ++i) {
4232 CaseClause* clause = clauses->at(i); 4242 CaseClause* clause = clauses->at(i);
4233 if (clause->is_default()) { 4243 if (clause->is_default()) {
4234 body_blocks.Add(NULL, zone()); 4244 body_blocks.Add(NULL, zone());
4235 if (default_id.IsNone()) default_id = clause->EntryId(); 4245 if (default_id.IsNone()) default_id = clause->EntryId();
4236 continue; 4246 continue;
4237 } 4247 }
4238 4248
4239 // Generate a compare and branch. 4249 // Generate a compare and branch.
4240 CHECK_ALIVE(VisitForValue(clause->label())); 4250 CHECK_ALIVE(VisitForValue(clause->label()));
4241 HValue* label_value = Pop(); 4251 HValue* label_value = Pop();
4242 4252
4243 Handle<Type> label_type = clause->label()->bounds().lower; 4253 Type* label_type = clause->label()->bounds().lower;
4244 Handle<Type> combined_type = clause->compare_type(); 4254 Type* combined_type = clause->compare_type();
4245 HControlInstruction* compare = BuildCompareInstruction( 4255 HControlInstruction* compare = BuildCompareInstruction(
4246 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, 4256 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type,
4247 combined_type, stmt->tag()->position(), clause->label()->position(), 4257 combined_type, stmt->tag()->position(), clause->label()->position(),
4248 clause->id()); 4258 clause->id());
4249 4259
4250 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 4260 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
4251 HBasicBlock* body_block = graph()->CreateBasicBlock(); 4261 HBasicBlock* body_block = graph()->CreateBasicBlock();
4252 body_blocks.Add(body_block, zone()); 4262 body_blocks.Add(body_block, zone());
4253 compare->SetSuccessorAt(0, body_block); 4263 compare->SetSuccessorAt(0, body_block);
4254 compare->SetSuccessorAt(1, next_test_block); 4264 compare->SetSuccessorAt(1, next_test_block);
(...skipping 1600 matching lines...) Expand 10 before | Expand all | Expand 10 after
5855 Deoptimizer::EAGER); 5865 Deoptimizer::EAGER);
5856 builder.End(); 5866 builder.End();
5857 } 5867 }
5858 HInstruction* instr = 5868 HInstruction* instr =
5859 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); 5869 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
5860 if (instr->HasObservableSideEffects()) { 5870 if (instr->HasObservableSideEffects()) {
5861 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 5871 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5862 } 5872 }
5863 } else { 5873 } else {
5864 HGlobalObject* global_object = Add<HGlobalObject>(); 5874 HGlobalObject* global_object = Add<HGlobalObject>();
5865 HStoreGlobalGeneric* instr = 5875 HStoreNamedGeneric* instr =
5866 Add<HStoreGlobalGeneric>(global_object, var->name(), 5876 Add<HStoreNamedGeneric>(global_object, var->name(),
5867 value, function_strict_mode_flag()); 5877 value, function_strict_mode_flag());
5868 USE(instr); 5878 USE(instr);
5869 ASSERT(instr->HasObservableSideEffects()); 5879 ASSERT(instr->HasObservableSideEffects());
5870 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 5880 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5871 } 5881 }
5872 } 5882 }
5873 5883
5874 5884
5875 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 5885 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
5876 Expression* target = expr->target(); 5886 Expression* target = expr->target();
(...skipping 1738 matching lines...) Expand 10 before | Expand all | Expand 10 after
7615 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 7625 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
7616 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 7626 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7617 HValue* right = Pop(); 7627 HValue* right = Pop();
7618 HValue* left = Pop(); 7628 HValue* left = Pop();
7619 Drop(1); // Receiver. 7629 Drop(1); // Receiver.
7620 HInstruction* result = HMul::NewImul(zone(), context(), left, right); 7630 HInstruction* result = HMul::NewImul(zone(), context(), left, right);
7621 ast_context()->ReturnInstruction(result, expr->id()); 7631 ast_context()->ReturnInstruction(result, expr->id());
7622 return true; 7632 return true;
7623 } 7633 }
7624 break; 7634 break;
7635 case kArrayPop: {
7636 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) {
7637 return false;
7638 }
7639 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
7640 ElementsKind elements_kind = receiver_map->elements_kind();
7641 if (!IsFastElementsKind(elements_kind)) return false;
7642 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7643
7644 Drop(expr->arguments()->length());
7645 HValue* result;
7646 HValue* checked_object;
7647 HValue* reduced_length;
7648 HValue* receiver = Pop();
7649 { NoObservableSideEffectsScope scope(this);
7650 checked_object = AddCheckMap(receiver, receiver_map);
7651 HValue* elements = AddLoadElements(checked_object);
7652 // Ensure that we aren't popping from a copy-on-write array.
7653 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
7654 Add<HCheckMaps>(
7655 elements, isolate()->factory()->fixed_array_map(), top_info());
7656 }
7657 HValue* length = Add<HLoadNamedField>(
7658 checked_object, HObjectAccess::ForArrayLength(elements_kind));
7659 reduced_length = AddUncasted<HSub>(length, graph()->GetConstant1());
7660 HValue* bounds_check = Add<HBoundsCheck>(
7661 graph()->GetConstant0(), length);
7662 result = AddElementAccess(elements, reduced_length, NULL,
7663 bounds_check, elements_kind, false);
7664 Factory* factory = isolate()->factory();
7665 double nan_double = FixedDoubleArray::hole_nan_as_double();
7666 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind)
7667 ? Add<HConstant>(factory->the_hole_value())
7668 : Add<HConstant>(nan_double);
7669 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
7670 elements_kind = FAST_HOLEY_ELEMENTS;
7671 }
7672 AddElementAccess(
7673 elements, reduced_length, hole, bounds_check, elements_kind, true);
7674 }
7675 Add<HStoreNamedField>(
7676 checked_object, HObjectAccess::ForArrayLength(elements_kind),
7677 reduced_length);
7678 ast_context()->ReturnValue(result);
7679 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
7680 return true;
7681 }
7625 default: 7682 default:
7626 // Not yet supported for inlining. 7683 // Not yet supported for inlining.
7627 break; 7684 break;
7628 } 7685 }
7629 return false; 7686 return false;
7630 } 7687 }
7631 7688
7632 7689
7633 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { 7690 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) {
7634 Expression* callee = expr->expression(); 7691 Expression* callee = expr->expression();
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
7945 8002
7946 8003
7947 void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) { 8004 void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) {
7948 NoObservableSideEffectsScope no_effects(this); 8005 NoObservableSideEffectsScope no_effects(this);
7949 8006
7950 int argument_count = expr->arguments()->length(); 8007 int argument_count = expr->arguments()->length();
7951 // We should at least have the constructor on the expression stack. 8008 // We should at least have the constructor on the expression stack.
7952 HValue* constructor = environment()->ExpressionStackAt(argument_count); 8009 HValue* constructor = environment()->ExpressionStackAt(argument_count);
7953 8010
7954 ElementsKind kind = expr->elements_kind(); 8011 ElementsKind kind = expr->elements_kind();
7955 Handle<Cell> cell = expr->allocation_info_cell(); 8012 Handle<AllocationSite> site = expr->allocation_site();
7956 Handle<AllocationSite> site(AllocationSite::cast(cell->value())); 8013 ASSERT(!site.is_null());
7957 8014
7958 // Register on the site for deoptimization if the cell value changes. 8015 // Register on the site for deoptimization if the transition feedback changes.
7959 AllocationSite::AddDependentCompilationInfo( 8016 AllocationSite::AddDependentCompilationInfo(
7960 site, AllocationSite::TRANSITIONS, top_info()); 8017 site, AllocationSite::TRANSITIONS, top_info());
7961 HInstruction* cell_instruction = Add<HConstant>(cell); 8018 HInstruction* site_instruction = Add<HConstant>(site);
7962 8019
7963 // In the single constant argument case, we may have to adjust elements kind 8020 // In the single constant argument case, we may have to adjust elements kind
7964 // to avoid creating a packed non-empty array. 8021 // to avoid creating a packed non-empty array.
7965 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { 8022 if (argument_count == 1 && !IsHoleyElementsKind(kind)) {
7966 HValue* argument = environment()->Top(); 8023 HValue* argument = environment()->Top();
7967 if (argument->IsConstant()) { 8024 if (argument->IsConstant()) {
7968 HConstant* constant_argument = HConstant::cast(argument); 8025 HConstant* constant_argument = HConstant::cast(argument);
7969 ASSERT(constant_argument->HasSmiValue()); 8026 ASSERT(constant_argument->HasSmiValue());
7970 int constant_array_size = constant_argument->Integer32Value(); 8027 int constant_array_size = constant_argument->Integer32Value();
7971 if (constant_array_size != 0) { 8028 if (constant_array_size != 0) {
7972 kind = GetHoleyElementsKind(kind); 8029 kind = GetHoleyElementsKind(kind);
7973 } 8030 }
7974 } 8031 }
7975 } 8032 }
7976 8033
7977 // Build the array. 8034 // Build the array.
7978 JSArrayBuilder array_builder(this, 8035 JSArrayBuilder array_builder(this,
7979 kind, 8036 kind,
7980 cell_instruction, 8037 site_instruction,
7981 constructor, 8038 constructor,
7982 DISABLE_ALLOCATION_SITES); 8039 DISABLE_ALLOCATION_SITES);
7983 HValue* new_object; 8040 HValue* new_object;
7984 if (argument_count == 0) { 8041 if (argument_count == 0) {
7985 new_object = array_builder.AllocateEmptyArray(); 8042 new_object = array_builder.AllocateEmptyArray();
7986 } else if (argument_count == 1) { 8043 } else if (argument_count == 1) {
7987 HValue* argument = environment()->Top(); 8044 HValue* argument = environment()->Top();
7988 new_object = BuildAllocateArrayFromLength(&array_builder, argument); 8045 new_object = BuildAllocateArrayFromLength(&array_builder, argument);
7989 } else { 8046 } else {
7990 HValue* length = Add<HConstant>(argument_count); 8047 HValue* length = Add<HConstant>(argument_count);
(...skipping 29 matching lines...) Expand all
8020 8077
8021 8078
8022 bool HOptimizedGraphBuilder::IsCallNewArrayInlineable(CallNew* expr) { 8079 bool HOptimizedGraphBuilder::IsCallNewArrayInlineable(CallNew* expr) {
8023 bool inline_ok = false; 8080 bool inline_ok = false;
8024 Handle<JSFunction> caller = current_info()->closure(); 8081 Handle<JSFunction> caller = current_info()->closure();
8025 Handle<JSFunction> target(isolate()->global_context()->array_function(), 8082 Handle<JSFunction> target(isolate()->global_context()->array_function(),
8026 isolate()); 8083 isolate());
8027 int argument_count = expr->arguments()->length(); 8084 int argument_count = expr->arguments()->length();
8028 // We should have the function plus array arguments on the environment stack. 8085 // We should have the function plus array arguments on the environment stack.
8029 ASSERT(environment()->length() >= (argument_count + 1)); 8086 ASSERT(environment()->length() >= (argument_count + 1));
8030 Handle<Cell> cell = expr->allocation_info_cell(); 8087 Handle<AllocationSite> site = expr->allocation_site();
8031 AllocationSite* site = AllocationSite::cast(cell->value()); 8088 ASSERT(!site.is_null());
8089
8032 if (site->CanInlineCall()) { 8090 if (site->CanInlineCall()) {
8033 // We also want to avoid inlining in certain 1 argument scenarios. 8091 // We also want to avoid inlining in certain 1 argument scenarios.
8034 if (argument_count == 1) { 8092 if (argument_count == 1) {
8035 HValue* argument = Top(); 8093 HValue* argument = Top();
8036 if (argument->IsConstant()) { 8094 if (argument->IsConstant()) {
8037 // Do not inline if the constant length argument is not a smi or 8095 // Do not inline if the constant length argument is not a smi or
8038 // outside the valid range for a fast array. 8096 // outside the valid range for a fast array.
8039 HConstant* constant_argument = HConstant::cast(argument); 8097 HConstant* constant_argument = HConstant::cast(argument);
8040 if (constant_argument->HasSmiValue()) { 8098 if (constant_argument->HasSmiValue()) {
8041 int value = constant_argument->Integer32Value(); 8099 int value = constant_argument->Integer32Value();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
8160 environment()->SetExpressionStackAt(receiver_index, function); 8218 environment()->SetExpressionStackAt(receiver_index, function);
8161 HInstruction* call = 8219 HInstruction* call =
8162 PreProcessCall(New<HCallNew>(function, argument_count)); 8220 PreProcessCall(New<HCallNew>(function, argument_count));
8163 return ast_context()->ReturnInstruction(call, expr->id()); 8221 return ast_context()->ReturnInstruction(call, expr->id());
8164 } else { 8222 } else {
8165 // The constructor function is both an operand to the instruction and an 8223 // The constructor function is both an operand to the instruction and an
8166 // argument to the construct call. 8224 // argument to the construct call.
8167 Handle<JSFunction> array_function( 8225 Handle<JSFunction> array_function(
8168 isolate()->global_context()->array_function(), isolate()); 8226 isolate()->global_context()->array_function(), isolate());
8169 bool use_call_new_array = expr->target().is_identical_to(array_function); 8227 bool use_call_new_array = expr->target().is_identical_to(array_function);
8170 Handle<Cell> cell = expr->allocation_info_cell();
8171 if (use_call_new_array && IsCallNewArrayInlineable(expr)) { 8228 if (use_call_new_array && IsCallNewArrayInlineable(expr)) {
8172 // Verify we are still calling the array function for our native context. 8229 // Verify we are still calling the array function for our native context.
8173 Add<HCheckValue>(function, array_function); 8230 Add<HCheckValue>(function, array_function);
8174 BuildInlinedCallNewArray(expr); 8231 BuildInlinedCallNewArray(expr);
8175 return; 8232 return;
8176 } 8233 }
8177 8234
8178 HBinaryCall* call; 8235 HBinaryCall* call;
8179 if (use_call_new_array) { 8236 if (use_call_new_array) {
8180 Add<HCheckValue>(function, array_function); 8237 Add<HCheckValue>(function, array_function);
8181 call = New<HCallNewArray>(function, argument_count, cell, 8238 call = New<HCallNewArray>(function, argument_count,
8182 expr->elements_kind()); 8239 expr->elements_kind());
8183 } else { 8240 } else {
8184 call = New<HCallNew>(function, argument_count); 8241 call = New<HCallNew>(function, argument_count);
8185 } 8242 }
8186 PreProcessCall(call); 8243 PreProcessCall(call);
8187 return ast_context()->ReturnInstruction(call, expr->id()); 8244 return ast_context()->ReturnInstruction(call, expr->id());
8188 } 8245 }
8189 } 8246 }
8190 8247
8191 8248
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
8544 CreateJoin(materialize_false, materialize_true, expr->id()); 8601 CreateJoin(materialize_false, materialize_true, expr->id());
8545 set_current_block(join); 8602 set_current_block(join);
8546 if (join != NULL) return ast_context()->ReturnValue(Pop()); 8603 if (join != NULL) return ast_context()->ReturnValue(Pop());
8547 } 8604 }
8548 8605
8549 8606
8550 HInstruction* HOptimizedGraphBuilder::BuildIncrement( 8607 HInstruction* HOptimizedGraphBuilder::BuildIncrement(
8551 bool returns_original_input, 8608 bool returns_original_input,
8552 CountOperation* expr) { 8609 CountOperation* expr) {
8553 // The input to the count operation is on top of the expression stack. 8610 // The input to the count operation is on top of the expression stack.
8554 Handle<Type> info = expr->type(); 8611 Representation rep = Representation::FromType(expr->type());
8555 Representation rep = Representation::FromType(info);
8556 if (rep.IsNone() || rep.IsTagged()) { 8612 if (rep.IsNone() || rep.IsTagged()) {
8557 rep = Representation::Smi(); 8613 rep = Representation::Smi();
8558 } 8614 }
8559 8615
8560 if (returns_original_input) { 8616 if (returns_original_input) {
8561 // We need an explicit HValue representing ToNumber(input). The 8617 // We need an explicit HValue representing ToNumber(input). The
8562 // actual HChange instruction we need is (sometimes) added in a later 8618 // actual HChange instruction we need is (sometimes) added in a later
8563 // phase, so it is not available now to be used as an input to HAdd and 8619 // phase, so it is not available now to be used as an input to HAdd and
8564 // as the return value. 8620 // as the return value.
8565 HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep); 8621 HInstruction* number_input = AddUncasted<HForceRepresentation>(Pop(), rep);
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
8796 if (right_const->HasInteger32Value() && 8852 if (right_const->HasInteger32Value() &&
8797 (right_const->Integer32Value() & 0x1f) != 0) { 8853 (right_const->Integer32Value() & 0x1f) != 0) {
8798 return false; 8854 return false;
8799 } 8855 }
8800 } 8856 }
8801 return true; 8857 return true;
8802 } 8858 }
8803 8859
8804 8860
8805 HValue* HGraphBuilder::EnforceNumberType(HValue* number, 8861 HValue* HGraphBuilder::EnforceNumberType(HValue* number,
8806 Handle<Type> expected) { 8862 Type* expected) {
8807 if (expected->Is(Type::Smi())) { 8863 if (expected->Is(Type::Smi())) {
8808 return AddUncasted<HForceRepresentation>(number, Representation::Smi()); 8864 return AddUncasted<HForceRepresentation>(number, Representation::Smi());
8809 } 8865 }
8810 if (expected->Is(Type::Signed32())) { 8866 if (expected->Is(Type::Signed32())) {
8811 return AddUncasted<HForceRepresentation>(number, 8867 return AddUncasted<HForceRepresentation>(number,
8812 Representation::Integer32()); 8868 Representation::Integer32());
8813 } 8869 }
8814 return number; 8870 return number;
8815 } 8871 }
8816 8872
8817 8873
8818 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) { 8874 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) {
8819 if (value->IsConstant()) { 8875 if (value->IsConstant()) {
8820 HConstant* constant = HConstant::cast(value); 8876 HConstant* constant = HConstant::cast(value);
8821 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); 8877 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone());
8822 if (number.has_value) { 8878 if (number.has_value) {
8823 *expected = Type::Number(isolate()); 8879 *expected = Type::Number(zone());
8824 return AddInstruction(number.value); 8880 return AddInstruction(number.value);
8825 } 8881 }
8826 } 8882 }
8827 8883
8828 // We put temporary values on the stack, which don't correspond to anything 8884 // We put temporary values on the stack, which don't correspond to anything
8829 // in baseline code. Since nothing is observable we avoid recording those 8885 // in baseline code. Since nothing is observable we avoid recording those
8830 // pushes with a NoObservableSideEffectsScope. 8886 // pushes with a NoObservableSideEffectsScope.
8831 NoObservableSideEffectsScope no_effects(this); 8887 NoObservableSideEffectsScope no_effects(this);
8832 8888
8833 Handle<Type> expected_type = *expected; 8889 Type* expected_type = *expected;
8834 8890
8835 // Separate the number type from the rest. 8891 // Separate the number type from the rest.
8836 Handle<Type> expected_obj = Type::Intersect( 8892 Type* expected_obj =
8837 expected_type, Type::NonNumber(isolate()), isolate()); 8893 Type::Intersect(expected_type, Type::NonNumber(zone()), zone());
8838 Handle<Type> expected_number = Type::Intersect( 8894 Type* expected_number =
8839 expected_type, Type::Number(isolate()), isolate()); 8895 Type::Intersect(expected_type, Type::Number(zone()), zone());
8840 8896
8841 // We expect to get a number. 8897 // We expect to get a number.
8842 // (We need to check first, since Type::None->Is(Type::Any()) == true. 8898 // (We need to check first, since Type::None->Is(Type::Any()) == true.
8843 if (expected_obj->Is(Type::None())) { 8899 if (expected_obj->Is(Type::None())) {
8844 ASSERT(!expected_number->Is(Type::None())); 8900 ASSERT(!expected_number->Is(Type::None(zone())));
8845 return value; 8901 return value;
8846 } 8902 }
8847 8903
8848 if (expected_obj->Is(Type::Undefined())) { 8904 if (expected_obj->Is(Type::Undefined(zone()))) {
8849 // This is already done by HChange. 8905 // This is already done by HChange.
8850 *expected = Type::Union( 8906 *expected = Type::Union(expected_number, Type::Double(zone()), zone());
8851 expected_number, Type::Double(isolate()), isolate());
8852 return value; 8907 return value;
8853 } 8908 }
8854 8909
8855 return value; 8910 return value;
8856 } 8911 }
8857 8912
8858 8913
8859 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( 8914 HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
8860 BinaryOperation* expr, 8915 BinaryOperation* expr,
8861 HValue* left, 8916 HValue* left,
8862 HValue* right) { 8917 HValue* right) {
8863 Handle<Type> left_type = expr->left()->bounds().lower; 8918 Type* left_type = expr->left()->bounds().lower;
8864 Handle<Type> right_type = expr->right()->bounds().lower; 8919 Type* right_type = expr->right()->bounds().lower;
8865 Handle<Type> result_type = expr->bounds().lower; 8920 Type* result_type = expr->bounds().lower;
8866 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 8921 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
8867 Handle<AllocationSite> allocation_site = expr->allocation_site(); 8922 Handle<AllocationSite> allocation_site = expr->allocation_site();
8868 8923
8869 HAllocationMode allocation_mode = 8924 HAllocationMode allocation_mode =
8870 FLAG_allocation_site_pretenuring 8925 FLAG_allocation_site_pretenuring
8871 ? (allocation_site.is_null() 8926 ? (allocation_site.is_null()
8872 ? HAllocationMode(NOT_TENURED) 8927 ? HAllocationMode(NOT_TENURED)
8873 : HAllocationMode(allocation_site)) 8928 : HAllocationMode(allocation_site))
8874 : HAllocationMode(isolate()->heap()->GetPretenureMode()); 8929 : HAllocationMode(isolate()->heap()->GetPretenureMode());
8875 8930
8876 HValue* result = HGraphBuilder::BuildBinaryOperation( 8931 HValue* result = HGraphBuilder::BuildBinaryOperation(
8877 expr->op(), left, right, left_type, right_type, result_type, 8932 expr->op(), left, right, left_type, right_type, result_type,
8878 fixed_right_arg, allocation_mode); 8933 fixed_right_arg, allocation_mode);
8879 // Add a simulate after instructions with observable side effects, and 8934 // Add a simulate after instructions with observable side effects, and
8880 // after phis, which are the result of BuildBinaryOperation when we 8935 // after phis, which are the result of BuildBinaryOperation when we
8881 // inlined some complex subgraph. 8936 // inlined some complex subgraph.
8882 if (result->HasObservableSideEffects() || result->IsPhi()) { 8937 if (result->HasObservableSideEffects() || result->IsPhi()) {
8883 Push(result); 8938 Push(result);
8884 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8939 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
8885 Drop(1); 8940 Drop(1);
8886 } 8941 }
8887 return result; 8942 return result;
8888 } 8943 }
8889 8944
8890 8945
8891 HValue* HGraphBuilder::BuildBinaryOperation( 8946 HValue* HGraphBuilder::BuildBinaryOperation(
8892 Token::Value op, 8947 Token::Value op,
8893 HValue* left, 8948 HValue* left,
8894 HValue* right, 8949 HValue* right,
8895 Handle<Type> left_type, 8950 Type* left_type,
8896 Handle<Type> right_type, 8951 Type* right_type,
8897 Handle<Type> result_type, 8952 Type* result_type,
8898 Maybe<int> fixed_right_arg, 8953 Maybe<int> fixed_right_arg,
8899 HAllocationMode allocation_mode) { 8954 HAllocationMode allocation_mode) {
8900 8955
8901 Representation left_rep = Representation::FromType(left_type); 8956 Representation left_rep = Representation::FromType(left_type);
8902 Representation right_rep = Representation::FromType(right_type); 8957 Representation right_rep = Representation::FromType(right_type);
8903 8958
8904 bool maybe_string_add = op == Token::ADD && 8959 bool maybe_string_add = op == Token::ADD &&
8905 (left_type->Maybe(Type::String()) || 8960 (left_type->Maybe(Type::String()) ||
8906 right_type->Maybe(Type::String())); 8961 right_type->Maybe(Type::String()));
8907 8962
8908 if (left_type->Is(Type::None())) { 8963 if (left_type->Is(Type::None())) {
8909 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", 8964 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation",
8910 Deoptimizer::SOFT); 8965 Deoptimizer::SOFT);
8911 // TODO(rossberg): we should be able to get rid of non-continuous 8966 // TODO(rossberg): we should be able to get rid of non-continuous
8912 // defaults. 8967 // defaults.
8913 left_type = Type::Any(isolate()); 8968 left_type = Type::Any(zone());
8914 } else { 8969 } else {
8915 if (!maybe_string_add) left = TruncateToNumber(left, &left_type); 8970 if (!maybe_string_add) left = TruncateToNumber(left, &left_type);
8916 left_rep = Representation::FromType(left_type); 8971 left_rep = Representation::FromType(left_type);
8917 } 8972 }
8918 8973
8919 if (right_type->Is(Type::None())) { 8974 if (right_type->Is(Type::None())) {
8920 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", 8975 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation",
8921 Deoptimizer::SOFT); 8976 Deoptimizer::SOFT);
8922 right_type = Type::Any(isolate()); 8977 right_type = Type::Any(zone());
8923 } else { 8978 } else {
8924 if (!maybe_string_add) right = TruncateToNumber(right, &right_type); 8979 if (!maybe_string_add) right = TruncateToNumber(right, &right_type);
8925 right_rep = Representation::FromType(right_type); 8980 right_rep = Representation::FromType(right_type);
8926 } 8981 }
8927 8982
8928 // Special case for string addition here. 8983 // Special case for string addition here.
8929 if (op == Token::ADD && 8984 if (op == Token::ADD &&
8930 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { 8985 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) {
8931 // Validate type feedback for left argument. 8986 // Validate type feedback for left argument.
8932 if (left_type->Is(Type::String())) { 8987 if (left_type->Is(Type::String())) {
(...skipping 22 matching lines...) Expand all
8955 ASSERT(left_type->Is(Type::String())); 9010 ASSERT(left_type->Is(Type::String()));
8956 right = BuildNumberToString(right, right_type); 9011 right = BuildNumberToString(right, right_type);
8957 } else if (!right_type->Is(Type::String())) { 9012 } else if (!right_type->Is(Type::String())) {
8958 ASSERT(left_type->Is(Type::String())); 9013 ASSERT(left_type->Is(Type::String()));
8959 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); 9014 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT);
8960 Add<HPushArgument>(left); 9015 Add<HPushArgument>(left);
8961 Add<HPushArgument>(right); 9016 Add<HPushArgument>(right);
8962 return AddUncasted<HInvokeFunction>(function, 2); 9017 return AddUncasted<HInvokeFunction>(function, 2);
8963 } 9018 }
8964 9019
8965 // Inline the string addition into the stub when creating allocation 9020 // Fast path for empty constant strings.
8966 // mementos to gather allocation site feedback. 9021 if (left->IsConstant() &&
8967 if (graph()->info()->IsStub() && 9022 HConstant::cast(left)->HasStringValue() &&
8968 allocation_mode.CreateAllocationMementos()) { 9023 HConstant::cast(left)->StringValue()->length() == 0) {
8969 return BuildStringAdd(left, right, allocation_mode); 9024 return right;
9025 }
9026 if (right->IsConstant() &&
9027 HConstant::cast(right)->HasStringValue() &&
9028 HConstant::cast(right)->StringValue()->length() == 0) {
9029 return left;
8970 } 9030 }
8971 9031
8972 // Register the dependent code with the allocation site. 9032 // Register the dependent code with the allocation site.
8973 if (!allocation_mode.feedback_site().is_null()) { 9033 if (!allocation_mode.feedback_site().is_null()) {
8974 ASSERT(!graph()->info()->IsStub()); 9034 ASSERT(!graph()->info()->IsStub());
8975 Handle<AllocationSite> site(allocation_mode.feedback_site()); 9035 Handle<AllocationSite> site(allocation_mode.feedback_site());
8976 AllocationSite::AddDependentCompilationInfo( 9036 AllocationSite::AddDependentCompilationInfo(
8977 site, AllocationSite::TENURING, top_info()); 9037 site, AllocationSite::TENURING, top_info());
8978 } 9038 }
8979 9039
8980 // Inline string addition if we know that we'll create a cons string. 9040 // Inline the string addition into the stub when creating allocation
8981 if (left->IsConstant()) { 9041 // mementos to gather allocation site feedback, or if we can statically
8982 HConstant* c_left = HConstant::cast(left); 9042 // infer that we're going to create a cons string.
8983 if (c_left->HasStringValue()) { 9043 if ((graph()->info()->IsStub() &&
8984 int c_left_length = c_left->StringValue()->length(); 9044 allocation_mode.CreateAllocationMementos()) ||
8985 if (c_left_length == 0) { 9045 (left->IsConstant() &&
8986 return right; 9046 HConstant::cast(left)->HasStringValue() &&
8987 } else if (c_left_length + 1 >= ConsString::kMinLength) { 9047 HConstant::cast(left)->StringValue()->length() + 1 >=
8988 return BuildStringAdd(left, right, allocation_mode); 9048 ConsString::kMinLength) ||
8989 } 9049 (right->IsConstant() &&
8990 } 9050 HConstant::cast(right)->HasStringValue() &&
8991 } 9051 HConstant::cast(right)->StringValue()->length() + 1 >=
8992 if (right->IsConstant()) { 9052 ConsString::kMinLength)) {
8993 HConstant* c_right = HConstant::cast(right); 9053 return BuildStringAdd(left, right, allocation_mode);
8994 if (c_right->HasStringValue()) {
8995 int c_right_length = c_right->StringValue()->length();
8996 if (c_right_length == 0) {
8997 return left;
8998 } else if (c_right_length + 1 >= ConsString::kMinLength) {
8999 return BuildStringAdd(left, right, allocation_mode);
9000 }
9001 }
9002 } 9054 }
9003 9055
9004 // Fallback to using the string add stub. 9056 // Fallback to using the string add stub.
9005 return AddUncasted<HStringAdd>( 9057 return AddUncasted<HStringAdd>(
9006 left, right, allocation_mode.GetPretenureMode(), 9058 left, right, allocation_mode.GetPretenureMode(),
9007 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); 9059 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
9008 } 9060 }
9009 9061
9010 if (graph()->info()->IsStub()) { 9062 if (graph()->info()->IsStub()) {
9011 left = EnforceNumberType(left, left_type); 9063 left = EnforceNumberType(left, left_type);
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
9320 CallRuntime* call = expr->left()->AsCallRuntime(); 9372 CallRuntime* call = expr->left()->AsCallRuntime();
9321 ASSERT(call->arguments()->length() == 1); 9373 ASSERT(call->arguments()->length() == 1);
9322 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9374 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9323 HValue* value = Pop(); 9375 HValue* value = Pop();
9324 Literal* literal = expr->right()->AsLiteral(); 9376 Literal* literal = expr->right()->AsLiteral();
9325 Handle<String> rhs = Handle<String>::cast(literal->value()); 9377 Handle<String> rhs = Handle<String>::cast(literal->value());
9326 HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); 9378 HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs);
9327 return ast_context()->ReturnControl(instr, expr->id()); 9379 return ast_context()->ReturnControl(instr, expr->id());
9328 } 9380 }
9329 9381
9330 Handle<Type> left_type = expr->left()->bounds().lower; 9382 Type* left_type = expr->left()->bounds().lower;
9331 Handle<Type> right_type = expr->right()->bounds().lower; 9383 Type* right_type = expr->right()->bounds().lower;
9332 Handle<Type> combined_type = expr->combined_type(); 9384 Type* combined_type = expr->combined_type();
9333 9385
9334 CHECK_ALIVE(VisitForValue(expr->left())); 9386 CHECK_ALIVE(VisitForValue(expr->left()));
9335 CHECK_ALIVE(VisitForValue(expr->right())); 9387 CHECK_ALIVE(VisitForValue(expr->right()));
9336 9388
9337 if (FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); 9389 if (FLAG_emit_opt_code_positions) SetSourcePosition(expr->position());
9338 9390
9339 HValue* right = Pop(); 9391 HValue* right = Pop();
9340 HValue* left = Pop(); 9392 HValue* left = Pop();
9341 Token::Value op = expr->op(); 9393 Token::Value op = expr->op();
9342 9394
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
9399 expr->left()->position(), expr->right()->position(), expr->id()); 9451 expr->left()->position(), expr->right()->position(), expr->id());
9400 if (compare == NULL) return; // Bailed out. 9452 if (compare == NULL) return; // Bailed out.
9401 return ast_context()->ReturnControl(compare, expr->id()); 9453 return ast_context()->ReturnControl(compare, expr->id());
9402 } 9454 }
9403 9455
9404 9456
9405 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( 9457 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
9406 Token::Value op, 9458 Token::Value op,
9407 HValue* left, 9459 HValue* left,
9408 HValue* right, 9460 HValue* right,
9409 Handle<Type> left_type, 9461 Type* left_type,
9410 Handle<Type> right_type, 9462 Type* right_type,
9411 Handle<Type> combined_type, 9463 Type* combined_type,
9412 int left_position, 9464 int left_position,
9413 int right_position, 9465 int right_position,
9414 BailoutId bailout_id) { 9466 BailoutId bailout_id) {
9415 // Cases handled below depend on collected type feedback. They should 9467 // Cases handled below depend on collected type feedback. They should
9416 // soft deoptimize when there is no type feedback. 9468 // soft deoptimize when there is no type feedback.
9417 if (combined_type->Is(Type::None())) { 9469 if (combined_type->Is(Type::None())) {
9418 Add<HDeoptimize>("Insufficient type feedback for combined type " 9470 Add<HDeoptimize>("Insufficient type feedback for combined type "
9419 "of binary operation", 9471 "of binary operation",
9420 Deoptimizer::SOFT); 9472 Deoptimizer::SOFT);
9421 combined_type = left_type = right_type = Type::Any(isolate()); 9473 combined_type = left_type = right_type = Type::Any(zone());
9422 } 9474 }
9423 9475
9424 Representation left_rep = Representation::FromType(left_type); 9476 Representation left_rep = Representation::FromType(left_type);
9425 Representation right_rep = Representation::FromType(right_type); 9477 Representation right_rep = Representation::FromType(right_type);
9426 Representation combined_rep = Representation::FromType(combined_type); 9478 Representation combined_rep = Representation::FromType(combined_type);
9427 9479
9428 if (combined_type->Is(Type::Receiver())) { 9480 if (combined_type->Is(Type::Receiver())) {
9429 if (Token::IsEqualityOp(op)) { 9481 if (Token::IsEqualityOp(op)) {
9430 // Can we get away with map check and not instance type check? 9482 // Can we get away with map check and not instance type check?
9431 HValue* operand_to_check = 9483 HValue* operand_to_check =
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
9507 HValue* value = Pop(); 9559 HValue* value = Pop();
9508 if (expr->op() == Token::EQ_STRICT) { 9560 if (expr->op() == Token::EQ_STRICT) {
9509 HConstant* nil_constant = nil == kNullValue 9561 HConstant* nil_constant = nil == kNullValue
9510 ? graph()->GetConstantNull() 9562 ? graph()->GetConstantNull()
9511 : graph()->GetConstantUndefined(); 9563 : graph()->GetConstantUndefined();
9512 HCompareObjectEqAndBranch* instr = 9564 HCompareObjectEqAndBranch* instr =
9513 New<HCompareObjectEqAndBranch>(value, nil_constant); 9565 New<HCompareObjectEqAndBranch>(value, nil_constant);
9514 return ast_context()->ReturnControl(instr, expr->id()); 9566 return ast_context()->ReturnControl(instr, expr->id());
9515 } else { 9567 } else {
9516 ASSERT_EQ(Token::EQ, expr->op()); 9568 ASSERT_EQ(Token::EQ, expr->op());
9517 Handle<Type> type = expr->combined_type()->Is(Type::None()) 9569 Type* type = expr->combined_type()->Is(Type::None())
9518 ? Type::Any(isolate_) : expr->combined_type(); 9570 ? Type::Any(zone()) : expr->combined_type();
9519 HIfContinuation continuation; 9571 HIfContinuation continuation;
9520 BuildCompareNil(value, type, &continuation); 9572 BuildCompareNil(value, type, &continuation);
9521 return ast_context()->ReturnContinuation(&continuation, expr->id()); 9573 return ast_context()->ReturnContinuation(&continuation, expr->id());
9522 } 9574 }
9523 } 9575 }
9524 9576
9525 9577
9526 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 9578 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
9527 // If we share optimized code between different closures, the 9579 // If we share optimized code between different closures, the
9528 // this-function is not a constant, except inside an inlined body. 9580 // this-function is not a constant, except inside an inlined body.
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
10278 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 10330 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
10279 return Bailout(kInlinedRuntimeFunctionGetFromCache); 10331 return Bailout(kInlinedRuntimeFunctionGetFromCache);
10280 } 10332 }
10281 10333
10282 10334
10283 // Fast support for number to string. 10335 // Fast support for number to string.
10284 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 10336 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
10285 ASSERT_EQ(1, call->arguments()->length()); 10337 ASSERT_EQ(1, call->arguments()->length());
10286 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10338 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10287 HValue* number = Pop(); 10339 HValue* number = Pop();
10288 HValue* result = BuildNumberToString(number, Type::Number(isolate())); 10340 HValue* result = BuildNumberToString(number, Type::Any(zone()));
10289 return ast_context()->ReturnValue(result); 10341 return ast_context()->ReturnValue(result);
10290 } 10342 }
10291 10343
10292 10344
10293 // Fast call for custom callbacks. 10345 // Fast call for custom callbacks.
10294 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 10346 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
10295 // 1 ~ The function to call is not itself an argument to the call. 10347 // 1 ~ The function to call is not itself an argument to the call.
10296 int arg_count = call->arguments()->length() - 1; 10348 int arg_count = call->arguments()->length() - 1;
10297 ASSERT(arg_count >= 1); // There's always at least a receiver. 10349 ASSERT(arg_count >= 1); // There's always at least a receiver.
10298 10350
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
11014 if (ShouldProduceTraceOutput()) { 11066 if (ShouldProduceTraceOutput()) {
11015 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11067 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11016 } 11068 }
11017 11069
11018 #ifdef DEBUG 11070 #ifdef DEBUG
11019 graph_->Verify(false); // No full verify. 11071 graph_->Verify(false); // No full verify.
11020 #endif 11072 #endif
11021 } 11073 }
11022 11074
11023 } } // namespace v8::internal 11075 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698