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

Side by Side Diff: src/hydrogen.cc

Issue 168583006: Cleanup the double field tracking in Hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
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') | no next file » | 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 2803 matching lines...) Expand 10 before | Expand all | Expand 10 after
2814 // A constant map is fine. 2814 // A constant map is fine.
2815 Handle<Map> map(builder()->isolate()->get_initial_js_array_map(kind_), 2815 Handle<Map> map(builder()->isolate()->get_initial_js_array_map(kind_),
2816 builder()->isolate()); 2816 builder()->isolate());
2817 return builder()->Add<HConstant>(map); 2817 return builder()->Add<HConstant>(map);
2818 } 2818 }
2819 2819
2820 if (constructor_function_ != NULL && kind_ == GetInitialFastElementsKind()) { 2820 if (constructor_function_ != NULL && kind_ == GetInitialFastElementsKind()) {
2821 // No need for a context lookup if the kind_ matches the initial 2821 // No need for a context lookup if the kind_ matches the initial
2822 // map, because we can just load the map in that case. 2822 // map, because we can just load the map in that case.
2823 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 2823 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
2824 return builder()->AddLoadNamedField(constructor_function_, access); 2824 return builder()->Add<HLoadNamedField>(
2825 constructor_function_, static_cast<HValue*>(NULL), access);
2825 } 2826 }
2826 2827
2827 // TODO(mvstanton): we should always have a constructor function if we 2828 // TODO(mvstanton): we should always have a constructor function if we
2828 // are creating a stub. 2829 // are creating a stub.
2829 HInstruction* native_context = constructor_function_ != NULL 2830 HInstruction* native_context = constructor_function_ != NULL
2830 ? builder()->BuildGetNativeContext(constructor_function_) 2831 ? builder()->BuildGetNativeContext(constructor_function_)
2831 : builder()->BuildGetNativeContext(); 2832 : builder()->BuildGetNativeContext();
2832 2833
2833 HInstruction* index = builder()->Add<HConstant>( 2834 HInstruction* index = builder()->Add<HConstant>(
2834 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); 2835 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));
2835 2836
2836 HInstruction* map_array = builder()->Add<HLoadKeyed>( 2837 HInstruction* map_array = builder()->Add<HLoadKeyed>(
2837 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 2838 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2838 2839
2839 HInstruction* kind_index = builder()->Add<HConstant>(kind_); 2840 HInstruction* kind_index = builder()->Add<HConstant>(kind_);
2840 2841
2841 return builder()->Add<HLoadKeyed>( 2842 return builder()->Add<HLoadKeyed>(
2842 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 2843 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
2843 } 2844 }
2844 2845
2845 2846
2846 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 2847 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
2847 // Find the map near the constructor function 2848 // Find the map near the constructor function
2848 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 2849 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
2849 return builder()->AddLoadNamedField(constructor_function_, access); 2850 return builder()->Add<HLoadNamedField>(
2851 constructor_function_, static_cast<HValue*>(NULL), access);
2850 } 2852 }
2851 2853
2852 2854
2853 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 2855 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
2854 HValue* length_node) { 2856 HValue* length_node) {
2855 ASSERT(length_node != NULL); 2857 ASSERT(length_node != NULL);
2856 2858
2857 int base_size = JSArray::kSize; 2859 int base_size = JSArray::kSize;
2858 if (mode_ == TRACK_ALLOCATION_SITE) { 2860 if (mode_ == TRACK_ALLOCATION_SITE) {
2859 base_size += AllocationMemento::kSize; 2861 base_size += AllocationMemento::kSize;
(...skipping 2022 matching lines...) Expand 10 before | Expand all | Expand 10 after
4882 4884
4883 return kUseCell; 4885 return kUseCell;
4884 } 4886 }
4885 4887
4886 4888
4887 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 4889 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
4888 ASSERT(var->IsContextSlot()); 4890 ASSERT(var->IsContextSlot());
4889 HValue* context = environment()->context(); 4891 HValue* context = environment()->context();
4890 int length = current_info()->scope()->ContextChainLength(var->scope()); 4892 int length = current_info()->scope()->ContextChainLength(var->scope());
4891 while (length-- > 0) { 4893 while (length-- > 0) {
4892 context = AddLoadNamedField( 4894 context = Add<HLoadNamedField>(
4893 context, HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 4895 context, static_cast<HValue*>(NULL),
4896 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
4894 } 4897 }
4895 return context; 4898 return context;
4896 } 4899 }
4897 4900
4898 4901
4899 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 4902 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
4900 if (expr->is_this()) { 4903 if (expr->is_this()) {
4901 current_info()->set_this_has_uses(true); 4904 current_info()->set_this_has_uses(true);
4902 } 4905 }
4903 4906
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
5337 } 5340 }
5338 5341
5339 5342
5340 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, 5343 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object,
5341 Handle<Map> map) { 5344 Handle<Map> map) {
5342 BuildCheckHeapObject(object); 5345 BuildCheckHeapObject(object);
5343 return Add<HCheckMaps>(object, map, top_info()); 5346 return Add<HCheckMaps>(object, map, top_info());
5344 } 5347 }
5345 5348
5346 5349
5350 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField(
5351 PropertyAccessInfo* info,
5352 HValue* checked_object) {
5353 HObjectAccess access = info->access();
5354 if (access.representation().IsDouble()) {
5355 // Load the heap number.
5356 checked_object = Add<HLoadNamedField>(
5357 checked_object, static_cast<HValue*>(NULL),
5358 access.WithRepresentation(Representation::Tagged()));
5359 checked_object->set_type(HType::HeapNumber());
5360 // Load the double value from it.
5361 access = HObjectAccess::ForHeapNumberValue();
5362 }
5363 return New<HLoadNamedField>(
5364 checked_object, static_cast<HValue*>(NULL), access);
5365 }
5366
5367
5347 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 5368 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
5348 PropertyAccessInfo* info, 5369 PropertyAccessInfo* info,
5349 HValue* checked_object, 5370 HValue* checked_object,
5350 HValue* value) { 5371 HValue* value) {
5351 bool transition_to_field = info->lookup()->IsTransition(); 5372 bool transition_to_field = info->lookup()->IsTransition();
5352 // TODO(verwaest): Move this logic into PropertyAccessInfo. 5373 // TODO(verwaest): Move this logic into PropertyAccessInfo.
5353 HObjectAccess field_access = HObjectAccess::ForField( 5374 HObjectAccess field_access = HObjectAccess::ForField(
5354 info->map(), info->lookup(), info->name()); 5375 info->map(), info->lookup(), info->name());
5355 5376
5356 HStoreNamedField *instr; 5377 HStoreNamedField *instr;
5357 if (FLAG_track_double_fields && field_access.representation().IsDouble()) { 5378 if (field_access.representation().IsDouble()) {
5358 HObjectAccess heap_number_access = 5379 HObjectAccess heap_number_access =
5359 field_access.WithRepresentation(Representation::Tagged()); 5380 field_access.WithRepresentation(Representation::Tagged());
5360 if (transition_to_field) { 5381 if (transition_to_field) {
5361 // The store requires a mutable HeapNumber to be allocated. 5382 // The store requires a mutable HeapNumber to be allocated.
5362 NoObservableSideEffectsScope no_side_effects(this); 5383 NoObservableSideEffectsScope no_side_effects(this);
5363 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); 5384 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
5364 5385
5365 PretenureFlag pretenure_flag = !FLAG_allocation_site_pretenuring ? 5386 PretenureFlag pretenure_flag = !FLAG_allocation_site_pretenuring ?
5366 isolate()->heap()->GetPretenureMode() : NOT_TENURED; 5387 isolate()->heap()->GetPretenureMode() : NOT_TENURED;
5367 5388
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
5608 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 5629 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder());
5609 } 5630 }
5610 5631
5611 if (!info->lookup()->IsFound()) { 5632 if (!info->lookup()->IsFound()) {
5612 ASSERT(info->IsLoad()); 5633 ASSERT(info->IsLoad());
5613 return graph()->GetConstantUndefined(); 5634 return graph()->GetConstantUndefined();
5614 } 5635 }
5615 5636
5616 if (info->lookup()->IsField()) { 5637 if (info->lookup()->IsField()) {
5617 if (info->IsLoad()) { 5638 if (info->IsLoad()) {
5618 return BuildLoadNamedField(checked_holder, info->access()); 5639 return BuildLoadNamedField(info, checked_holder);
5619 } else { 5640 } else {
5620 return BuildStoreNamedField(info, checked_object, value); 5641 return BuildStoreNamedField(info, checked_object, value);
5621 } 5642 }
5622 } 5643 }
5623 5644
5624 if (info->lookup()->IsTransition()) { 5645 if (info->lookup()->IsTransition()) {
5625 ASSERT(!info->IsLoad()); 5646 ASSERT(!info->IsLoad());
5626 return BuildStoreNamedField(info, checked_object, value); 5647 return BuildStoreNamedField(info, checked_object, value);
5627 } 5648 }
5628 5649
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
6179 6200
6180 // If the throw definitely exits the function, we can finish with a dummy 6201 // If the throw definitely exits the function, we can finish with a dummy
6181 // control flow at this point. This is not the case if the throw is inside 6202 // control flow at this point. This is not the case if the throw is inside
6182 // an inlined function which may be replaced. 6203 // an inlined function which may be replaced.
6183 if (call_context() == NULL) { 6204 if (call_context() == NULL) {
6184 FinishExitCurrentBlock(New<HAbnormalExit>()); 6205 FinishExitCurrentBlock(New<HAbnormalExit>());
6185 } 6206 }
6186 } 6207 }
6187 6208
6188 6209
6189 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
6190 HObjectAccess access) {
6191 if (FLAG_track_double_fields && access.representation().IsDouble()) {
6192 // load the heap number
6193 HLoadNamedField* heap_number = Add<HLoadNamedField>(
6194 object, static_cast<HValue*>(NULL),
6195 access.WithRepresentation(Representation::Tagged()));
6196 heap_number->set_type(HType::HeapNumber());
6197 // load the double value from it
6198 return New<HLoadNamedField>(
6199 heap_number, static_cast<HValue*>(NULL),
6200 HObjectAccess::ForHeapNumberValue());
6201 }
6202 return New<HLoadNamedField>(object, static_cast<HValue*>(NULL), access);
6203 }
6204
6205
6206 HInstruction* HGraphBuilder::AddLoadNamedField(HValue* object,
6207 HObjectAccess access) {
6208 return AddInstruction(BuildLoadNamedField(object, access));
6209 }
6210
6211
6212 HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { 6210 HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) {
6213 if (string->IsConstant()) { 6211 if (string->IsConstant()) {
6214 HConstant* c_string = HConstant::cast(string); 6212 HConstant* c_string = HConstant::cast(string);
6215 if (c_string->HasStringValue()) { 6213 if (c_string->HasStringValue()) {
6216 return Add<HConstant>(c_string->StringValue()->map()->instance_type()); 6214 return Add<HConstant>(c_string->StringValue()->map()->instance_type());
6217 } 6215 }
6218 } 6216 }
6219 return AddLoadNamedField( 6217 return Add<HLoadNamedField>(
6220 AddLoadNamedField(string, HObjectAccess::ForMap()), 6218 Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
6221 HObjectAccess::ForMapInstanceType()); 6219 HObjectAccess::ForMap()),
6220 static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType());
6222 } 6221 }
6223 6222
6224 6223
6225 HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) { 6224 HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) {
6226 if (string->IsConstant()) { 6225 if (string->IsConstant()) {
6227 HConstant* c_string = HConstant::cast(string); 6226 HConstant* c_string = HConstant::cast(string);
6228 if (c_string->HasStringValue()) { 6227 if (c_string->HasStringValue()) {
6229 return Add<HConstant>(c_string->StringValue()->length()); 6228 return Add<HConstant>(c_string->StringValue()->length());
6230 } 6229 }
6231 } 6230 }
6232 return AddLoadNamedField(string, HObjectAccess::ForStringLength()); 6231 return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
6232 HObjectAccess::ForStringLength());
6233 } 6233 }
6234 6234
6235 6235
6236 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( 6236 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric(
6237 PropertyAccessType access_type, 6237 PropertyAccessType access_type,
6238 HValue* object, 6238 HValue* object,
6239 Handle<String> name, 6239 Handle<String> name,
6240 HValue* value, 6240 HValue* value,
6241 bool is_uninitialized) { 6241 bool is_uninitialized) {
6242 if (is_uninitialized) { 6242 if (is_uninitialized) {
(...skipping 5048 matching lines...) Expand 10 before | Expand all | Expand 10 after
11291 if (ShouldProduceTraceOutput()) { 11291 if (ShouldProduceTraceOutput()) {
11292 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11292 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11293 } 11293 }
11294 11294
11295 #ifdef DEBUG 11295 #ifdef DEBUG
11296 graph_->Verify(false); // No full verify. 11296 graph_->Verify(false); // No full verify.
11297 #endif 11297 #endif
11298 } 11298 }
11299 11299
11300 } } // namespace v8::internal 11300 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698