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

Side by Side Diff: src/hydrogen.cc

Issue 159933002: A64: Synchronize with r19289. (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/heap.cc ('k') | src/hydrogen-check-elimination.cc » ('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 2158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2169 !IsFixedTypedArrayElementsKind(elements_kind)) || 2169 !IsFixedTypedArrayElementsKind(elements_kind)) ||
2170 !is_js_array); 2170 !is_js_array);
2171 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 2171 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency
2172 // on a HElementsTransition instruction. The flag can also be removed if the 2172 // on a HElementsTransition instruction. The flag can also be removed if the
2173 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 2173 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
2174 // ElementsKind transitions. Finally, the dependency can be removed for stores 2174 // ElementsKind transitions. Finally, the dependency can be removed for stores
2175 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 2175 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
2176 // generated store code. 2176 // generated store code.
2177 if ((elements_kind == FAST_HOLEY_ELEMENTS) || 2177 if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
2178 (elements_kind == FAST_ELEMENTS && access_type == STORE)) { 2178 (elements_kind == FAST_ELEMENTS && access_type == STORE)) {
2179 checked_object->ClearGVNFlag(kDependsOnElementsKind); 2179 checked_object->ClearDependsOnFlag(kElementsKind);
2180 } 2180 }
2181 2181
2182 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); 2182 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
2183 bool fast_elements = IsFastObjectElementsKind(elements_kind); 2183 bool fast_elements = IsFastObjectElementsKind(elements_kind);
2184 HValue* elements = AddLoadElements(checked_object); 2184 HValue* elements = AddLoadElements(checked_object);
2185 if (access_type == STORE && (fast_elements || fast_smi_only_elements) && 2185 if (access_type == STORE && (fast_elements || fast_smi_only_elements) &&
2186 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 2186 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
2187 HCheckMaps* check_cow_map = Add<HCheckMaps>( 2187 HCheckMaps* check_cow_map = Add<HCheckMaps>(
2188 elements, isolate()->factory()->fixed_array_map(), top_info()); 2188 elements, isolate()->factory()->fixed_array_map(), top_info());
2189 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 2189 check_cow_map->ClearDependsOnFlag(kElementsKind);
2190 } 2190 }
2191 HInstruction* length = NULL; 2191 HInstruction* length = NULL;
2192 if (is_js_array) { 2192 if (is_js_array) {
2193 length = Add<HLoadNamedField>( 2193 length = Add<HLoadNamedField>(
2194 checked_object, static_cast<HValue*>(NULL), 2194 checked_object, static_cast<HValue*>(NULL),
2195 HObjectAccess::ForArrayLength(elements_kind)); 2195 HObjectAccess::ForArrayLength(elements_kind));
2196 } else { 2196 } else {
2197 length = AddLoadFixedArrayLength(elements); 2197 length = AddLoadFixedArrayLength(elements);
2198 } 2198 }
2199 length->set_type(HType::Smi()); 2199 length->set_type(HType::Smi());
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2253 checked_key = Add<HBoundsCheck>(key, length); 2253 checked_key = Add<HBoundsCheck>(key, length);
2254 2254
2255 if (access_type == STORE && (fast_elements || fast_smi_only_elements)) { 2255 if (access_type == STORE && (fast_elements || fast_smi_only_elements)) {
2256 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 2256 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
2257 NoObservableSideEffectsScope no_effects(this); 2257 NoObservableSideEffectsScope no_effects(this);
2258 elements = BuildCopyElementsOnWrite(checked_object, elements, 2258 elements = BuildCopyElementsOnWrite(checked_object, elements,
2259 elements_kind, length); 2259 elements_kind, length);
2260 } else { 2260 } else {
2261 HCheckMaps* check_cow_map = Add<HCheckMaps>( 2261 HCheckMaps* check_cow_map = Add<HCheckMaps>(
2262 elements, isolate()->factory()->fixed_array_map(), top_info()); 2262 elements, isolate()->factory()->fixed_array_map(), top_info());
2263 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 2263 check_cow_map->ClearDependsOnFlag(kElementsKind);
2264 } 2264 }
2265 } 2265 }
2266 } 2266 }
2267 return AddElementAccess(elements, checked_key, val, checked_object, 2267 return AddElementAccess(elements, checked_key, val, checked_object,
2268 elements_kind, access_type, load_mode); 2268 elements_kind, access_type, load_mode);
2269 } 2269 }
2270 2270
2271 2271
2272 2272
2273 HValue* HGraphBuilder::BuildAllocateArrayFromLength( 2273 HValue* HGraphBuilder::BuildAllocateArrayFromLength(
(...skipping 3030 matching lines...) Expand 10 before | Expand all | Expand 10 after
5304 } else { 5304 } else {
5305 // This is a normal store. 5305 // This is a normal store.
5306 instr = New<HStoreNamedField>( 5306 instr = New<HStoreNamedField>(
5307 checked_object->ActualValue(), field_access, value, 5307 checked_object->ActualValue(), field_access, value,
5308 transition_to_field ? INITIALIZING_STORE : STORE_TO_INITIALIZED_ENTRY); 5308 transition_to_field ? INITIALIZING_STORE : STORE_TO_INITIALIZED_ENTRY);
5309 } 5309 }
5310 5310
5311 if (transition_to_field) { 5311 if (transition_to_field) {
5312 HConstant* transition_constant = Add<HConstant>(info->transition()); 5312 HConstant* transition_constant = Add<HConstant>(info->transition());
5313 instr->SetTransition(transition_constant, top_info()); 5313 instr->SetTransition(transition_constant, top_info());
5314 instr->SetGVNFlag(kChangesMaps); 5314 instr->SetChangesFlag(kMaps);
5315 } 5315 }
5316 return instr; 5316 return instr;
5317 } 5317 }
5318 5318
5319 5319
5320 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( 5320 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible(
5321 PropertyAccessInfo* info) { 5321 PropertyAccessInfo* info) {
5322 if (!CanInlinePropertyAccess(type_)) return false; 5322 if (!CanInlinePropertyAccess(type_)) return false;
5323 5323
5324 // Currently only handle Type::Number as a polymorphic case. 5324 // Currently only handle Type::Number as a polymorphic case.
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after
6203 HValue* object, 6203 HValue* object,
6204 HValue* key, 6204 HValue* key,
6205 HValue* val, 6205 HValue* val,
6206 HValue* dependency, 6206 HValue* dependency,
6207 Handle<Map> map, 6207 Handle<Map> map,
6208 PropertyAccessType access_type, 6208 PropertyAccessType access_type,
6209 KeyedAccessStoreMode store_mode) { 6209 KeyedAccessStoreMode store_mode) {
6210 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(), 6210 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(),
6211 dependency); 6211 dependency);
6212 if (dependency) { 6212 if (dependency) {
6213 checked_object->ClearGVNFlag(kDependsOnElementsKind); 6213 checked_object->ClearDependsOnFlag(kElementsKind);
6214 } 6214 }
6215 6215
6216 if (access_type == STORE && map->prototype()->IsJSObject()) { 6216 if (access_type == STORE && map->prototype()->IsJSObject()) {
6217 // monomorphic stores need a prototype chain check because shape 6217 // monomorphic stores need a prototype chain check because shape
6218 // changes could allow callbacks on elements in the chain that 6218 // changes could allow callbacks on elements in the chain that
6219 // aren't compatible with monomorphic keyed stores. 6219 // aren't compatible with monomorphic keyed stores.
6220 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 6220 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
6221 Object* holder = map->prototype(); 6221 Object* holder = map->prototype();
6222 while (holder->GetPrototype(isolate())->IsJSObject()) { 6222 while (holder->GetPrototype(isolate())->IsJSObject()) {
6223 holder = holder->GetPrototype(isolate()); 6223 holder = holder->GetPrototype(isolate());
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
6683 6683
6684 if (constant->map()->CanOmitMapChecks()) { 6684 if (constant->map()->CanOmitMapChecks()) {
6685 constant->map()->AddDependentCompilationInfo( 6685 constant->map()->AddDependentCompilationInfo(
6686 DependentCode::kPrototypeCheckGroup, info); 6686 DependentCode::kPrototypeCheckGroup, info);
6687 return constant_value; 6687 return constant_value;
6688 } 6688 }
6689 6689
6690 AddInstruction(constant_value); 6690 AddInstruction(constant_value);
6691 HCheckMaps* check = 6691 HCheckMaps* check =
6692 Add<HCheckMaps>(constant_value, handle(constant->map()), info); 6692 Add<HCheckMaps>(constant_value, handle(constant->map()), info);
6693 check->ClearGVNFlag(kDependsOnElementsKind); 6693 check->ClearDependsOnFlag(kElementsKind);
6694 return check; 6694 return check;
6695 } 6695 }
6696 6696
6697 6697
6698 HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype, 6698 HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
6699 Handle<JSObject> holder) { 6699 Handle<JSObject> holder) {
6700 while (!prototype.is_identical_to(holder)) { 6700 while (!prototype.is_identical_to(holder)) {
6701 BuildConstantMapCheck(prototype, top_info()); 6701 BuildConstantMapCheck(prototype, top_info());
6702 prototype = handle(JSObject::cast(prototype->GetPrototype())); 6702 prototype = handle(JSObject::cast(prototype->GetPrototype()));
6703 } 6703 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
6767 target, static_cast<HValue*>(NULL), 6767 target, static_cast<HValue*>(NULL),
6768 HObjectAccess::ForFunctionContextPointer()); 6768 HObjectAccess::ForFunctionContextPointer());
6769 return NewArgumentAdaptorCall(target, context, 6769 return NewArgumentAdaptorCall(target, context,
6770 argument_count, param_count_value); 6770 argument_count, param_count_value);
6771 } 6771 }
6772 UNREACHABLE(); 6772 UNREACHABLE();
6773 return NULL; 6773 return NULL;
6774 } 6774 }
6775 6775
6776 6776
6777 class FunctionSorter {
6778 public:
6779 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { }
6780 FunctionSorter(int index, int ticks, int ast_length, int src_length)
6781 : index_(index),
6782 ticks_(ticks),
6783 ast_length_(ast_length),
6784 src_length_(src_length) { }
6785
6786 int index() const { return index_; }
6787 int ticks() const { return ticks_; }
6788 int ast_length() const { return ast_length_; }
6789 int src_length() const { return src_length_; }
6790
6791 private:
6792 int index_;
6793 int ticks_;
6794 int ast_length_;
6795 int src_length_;
6796 };
6797
6798
6799 inline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) {
6800 int diff = lhs.ticks() - rhs.ticks();
6801 if (diff != 0) return diff > 0;
6802 diff = lhs.ast_length() - rhs.ast_length();
6803 if (diff != 0) return diff < 0;
6804 return lhs.src_length() < rhs.src_length();
6805 }
6806
6807
6808 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( 6777 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
6809 Call* expr, 6778 Call* expr,
6810 HValue* receiver, 6779 HValue* receiver,
6811 SmallMapList* types, 6780 SmallMapList* types,
6812 Handle<String> name) { 6781 Handle<String> name) {
6813 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 6782 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
6814 FunctionSorter order[kMaxCallPolymorphism]; 6783 int order[kMaxCallPolymorphism];
6815 6784
6816 bool handle_smi = false; 6785 bool handle_smi = false;
6817 bool handled_string = false; 6786 bool handled_string = false;
6818 int ordered_functions = 0; 6787 int ordered_functions = 0;
6819 6788
6820 for (int i = 0; 6789 for (int i = 0;
6821 i < types->length() && ordered_functions < kMaxCallPolymorphism; 6790 i < types->length() && ordered_functions < kMaxCallPolymorphism;
6822 ++i) { 6791 ++i) {
6823 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); 6792 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
6824 if (info.CanAccessMonomorphic() && 6793 if (info.CanAccessMonomorphic() &&
6825 info.lookup()->IsConstant() && 6794 info.lookup()->IsConstant() &&
6826 info.constant()->IsJSFunction()) { 6795 info.constant()->IsJSFunction()) {
6827 if (info.type()->Is(Type::String())) { 6796 if (info.type()->Is(Type::String())) {
6828 if (handled_string) continue; 6797 if (handled_string) continue;
6829 handled_string = true; 6798 handled_string = true;
6830 } 6799 }
6831 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 6800 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
6832 if (info.type()->Is(Type::Number())) { 6801 if (info.type()->Is(Type::Number())) {
6833 handle_smi = true; 6802 handle_smi = true;
6834 } 6803 }
6835 expr->set_target(target); 6804 expr->set_target(target);
6836 order[ordered_functions++] = 6805 order[ordered_functions++] = i;
6837 FunctionSorter(i,
6838 expr->target()->shared()->profiler_ticks(),
6839 InliningAstSize(expr->target()),
6840 expr->target()->shared()->SourceSize());
6841 } 6806 }
6842 } 6807 }
6843 6808
6844 std::sort(order, order + ordered_functions);
6845
6846 HBasicBlock* number_block = NULL; 6809 HBasicBlock* number_block = NULL;
6847 HBasicBlock* join = NULL; 6810 HBasicBlock* join = NULL;
6848 handled_string = false; 6811 handled_string = false;
6849 int count = 0; 6812 int count = 0;
6850 6813
6851 for (int fn = 0; fn < ordered_functions; ++fn) { 6814 for (int fn = 0; fn < ordered_functions; ++fn) {
6852 int i = order[fn].index(); 6815 int i = order[fn];
6853 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); 6816 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
6854 if (info.type()->Is(Type::String())) { 6817 if (info.type()->Is(Type::String())) {
6855 if (handled_string) continue; 6818 if (handled_string) continue;
6856 handled_string = true; 6819 handled_string = true;
6857 } 6820 }
6858 // Reloads the target. 6821 // Reloads the target.
6859 info.CanAccessMonomorphic(); 6822 info.CanAccessMonomorphic();
6860 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 6823 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
6861 6824
6862 expr->set_target(target); 6825 expr->set_target(target);
(...skipping 2985 matching lines...) Expand 10 before | Expand all | Expand 10 after
9848 HInstruction* double_box = 9811 HInstruction* double_box =
9849 Add<HAllocate>(heap_number_constant, HType::HeapNumber(), 9812 Add<HAllocate>(heap_number_constant, HType::HeapNumber(),
9850 pretenure_flag, HEAP_NUMBER_TYPE); 9813 pretenure_flag, HEAP_NUMBER_TYPE);
9851 AddStoreMapConstant(double_box, 9814 AddStoreMapConstant(double_box,
9852 isolate()->factory()->heap_number_map()); 9815 isolate()->factory()->heap_number_map());
9853 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(), 9816 Add<HStoreNamedField>(double_box, HObjectAccess::ForHeapNumberValue(),
9854 Add<HConstant>(value)); 9817 Add<HConstant>(value));
9855 value_instruction = double_box; 9818 value_instruction = double_box;
9856 } else if (representation.IsSmi() && value->IsUninitialized()) { 9819 } else if (representation.IsSmi() && value->IsUninitialized()) {
9857 value_instruction = graph()->GetConstant0(); 9820 value_instruction = graph()->GetConstant0();
9821 // Ensure that Constant0 is stored as smi.
9822 access = access.WithRepresentation(representation);
9858 } else { 9823 } else {
9859 value_instruction = Add<HConstant>(value); 9824 value_instruction = Add<HConstant>(value);
9860 } 9825 }
9861 9826
9862 Add<HStoreNamedField>(object, access, value_instruction); 9827 Add<HStoreNamedField>(object, access, value_instruction);
9863 } 9828 }
9864 } 9829 }
9865 9830
9866 int inobject_properties = boilerplate_object->map()->inobject_properties(); 9831 int inobject_properties = boilerplate_object->map()->inobject_properties();
9867 HInstruction* value_instruction = 9832 HInstruction* value_instruction =
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
10325 10290
10326 // Check if object is a JSValue. 10291 // Check if object is a JSValue.
10327 IfBuilder if_objectisvalue(this); 10292 IfBuilder if_objectisvalue(this);
10328 if_objectisvalue.If<HHasInstanceTypeAndBranch>(object, JS_VALUE_TYPE); 10293 if_objectisvalue.If<HHasInstanceTypeAndBranch>(object, JS_VALUE_TYPE);
10329 if_objectisvalue.Then(); 10294 if_objectisvalue.Then();
10330 { 10295 {
10331 // Create in-object property store to kValueOffset. 10296 // Create in-object property store to kValueOffset.
10332 Add<HStoreNamedField>(object, 10297 Add<HStoreNamedField>(object,
10333 HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset), 10298 HObjectAccess::ForObservableJSObjectOffset(JSValue::kValueOffset),
10334 value); 10299 value);
10300 if (!ast_context()->IsEffect()) {
10301 Push(value);
10302 }
10335 Add<HSimulate>(call->id(), FIXED_SIMULATE); 10303 Add<HSimulate>(call->id(), FIXED_SIMULATE);
10336 } 10304 }
10337 if_objectisvalue.Else(); 10305 if_objectisvalue.Else();
10338 { 10306 {
10339 // Nothing to do in this case. 10307 // Nothing to do in this case.
10308 if (!ast_context()->IsEffect()) {
10309 Push(value);
10310 }
10340 Add<HSimulate>(call->id(), FIXED_SIMULATE); 10311 Add<HSimulate>(call->id(), FIXED_SIMULATE);
10341 } 10312 }
10342 if_objectisvalue.End(); 10313 if_objectisvalue.End();
10314 if (!ast_context()->IsEffect()) {
10315 Drop(1);
10316 }
10343 return ast_context()->ReturnValue(value); 10317 return ast_context()->ReturnValue(value);
10344 } 10318 }
10345 10319
10346 10320
10347 // Fast support for charCodeAt(n). 10321 // Fast support for charCodeAt(n).
10348 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 10322 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
10349 ASSERT(call->arguments()->length() == 2); 10323 ASSERT(call->arguments()->length() == 2);
10350 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10324 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10351 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 10325 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
10352 HValue* index = Pop(); 10326 HValue* index = Pop();
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
11197 if (ShouldProduceTraceOutput()) { 11171 if (ShouldProduceTraceOutput()) {
11198 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11172 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11199 } 11173 }
11200 11174
11201 #ifdef DEBUG 11175 #ifdef DEBUG
11202 graph_->Verify(false); // No full verify. 11176 graph_->Verify(false); // No full verify.
11203 #endif 11177 #endif
11204 } 11178 }
11205 11179
11206 } } // namespace v8::internal 11180 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/hydrogen-check-elimination.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698