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

Side by Side Diff: src/hydrogen-instructions.cc

Issue 148573005: A64: Synchronize with r16249. (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-instructions.h ('k') | src/hydrogen-mark-deoptimize.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 383
384 HUseListNode* HUseListNode::tail() { 384 HUseListNode* HUseListNode::tail() {
385 // Skip and remove dead items in the use list. 385 // Skip and remove dead items in the use list.
386 while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) { 386 while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) {
387 tail_ = tail_->tail_; 387 tail_ = tail_->tail_;
388 } 388 }
389 return tail_; 389 return tail_;
390 } 390 }
391 391
392 392
393 bool HValue::CheckUsesForFlag(Flag f) { 393 bool HValue::CheckUsesForFlag(Flag f) const {
394 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 394 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
395 if (it.value()->IsSimulate()) continue; 395 if (it.value()->IsSimulate()) continue;
396 if (!it.value()->CheckFlag(f)) return false; 396 if (!it.value()->CheckFlag(f)) return false;
397 } 397 }
398 return true; 398 return true;
399 } 399 }
400 400
401 401
402 bool HValue::HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) { 402 bool HValue::HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const {
403 bool return_value = false; 403 bool return_value = false;
404 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 404 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
405 if (it.value()->IsSimulate()) continue; 405 if (it.value()->IsSimulate()) continue;
406 if (!it.value()->CheckFlag(f)) return false; 406 if (!it.value()->CheckFlag(f)) return false;
407 return_value = true; 407 return_value = true;
408 } 408 }
409 return return_value; 409 return return_value;
410 } 410 }
411 411
412 412
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 // A change from an integer32 can be replaced by the integer32 value. 1280 // A change from an integer32 can be replaced by the integer32 value.
1281 if (dividend->IsChange() && 1281 if (dividend->IsChange() &&
1282 HChange::cast(dividend)->from().IsInteger32()) { 1282 HChange::cast(dividend)->from().IsInteger32()) {
1283 return HChange::cast(dividend)->value(); 1283 return HChange::cast(dividend)->value();
1284 } 1284 }
1285 return NULL; 1285 return NULL;
1286 } 1286 }
1287 1287
1288 1288
1289 HValue* HUnaryMathOperation::Canonicalize() { 1289 HValue* HUnaryMathOperation::Canonicalize() {
1290 if (op() == kMathRound || op() == kMathFloor) {
1291 HValue* val = value();
1292 if (val->IsChange()) val = HChange::cast(val)->value();
1293
1294 // If the input is smi or integer32 then we replace the instruction with its
1295 // input.
1296 if (val->representation().IsSmiOrInteger32()) {
1297 if (!val->representation().Equals(representation())) {
1298 HChange* result = new(block()->zone()) HChange(
1299 val, representation(), false, false);
1300 result->InsertBefore(this);
1301 return result;
1302 }
1303 return val;
1304 }
1305 }
1306
1290 if (op() == kMathFloor) { 1307 if (op() == kMathFloor) {
1291 HValue* val = value(); 1308 HValue* val = value();
1292 if (val->IsChange()) val = HChange::cast(val)->value(); 1309 if (val->IsChange()) val = HChange::cast(val)->value();
1293 1310 if (val->IsDiv() && (val->UseCount() == 1)) {
1294 // If the input is integer32 then we replace the floor instruction 1311 HDiv* hdiv = HDiv::cast(val);
1295 // with its input.
1296 if (val->representation().IsSmiOrInteger32()) return val;
1297
1298 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \
1299 defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_A64)
1300 if (value()->IsDiv() && (value()->UseCount() == 1)) {
1301 // TODO(2038): Implement this optimization for non ARM architectures.
1302 HDiv* hdiv = HDiv::cast(value());
1303 HValue* left = hdiv->left(); 1312 HValue* left = hdiv->left();
1304 HValue* right = hdiv->right(); 1313 HValue* right = hdiv->right();
1305 // Try to simplify left and right values of the division. 1314 // Try to simplify left and right values of the division.
1306 HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left); 1315 HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left);
1307 if (new_left == NULL && 1316 if (new_left == NULL &&
1308 hdiv->observed_input_representation(1).IsSmiOrInteger32()) { 1317 hdiv->observed_input_representation(1).IsSmiOrInteger32()) {
1309 new_left = new(block()->zone()) HChange( 1318 new_left = new(block()->zone()) HChange(
1310 left, Representation::Integer32(), false, false, false); 1319 left, Representation::Integer32(), false, false);
1311 HChange::cast(new_left)->InsertBefore(this); 1320 HChange::cast(new_left)->InsertBefore(this);
1312 } 1321 }
1313 HValue* new_right = 1322 HValue* new_right =
1314 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right); 1323 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right);
1315 if (new_right == NULL && 1324 if (new_right == NULL &&
1316 #if V8_TARGET_ARCH_ARM 1325 #if V8_TARGET_ARCH_ARM
1317 CpuFeatures::IsSupported(SUDIV) && 1326 CpuFeatures::IsSupported(SUDIV) &&
1318 #endif 1327 #endif
1319 hdiv->observed_input_representation(2).IsSmiOrInteger32()) { 1328 hdiv->observed_input_representation(2).IsSmiOrInteger32()) {
1320 new_right = new(block()->zone()) HChange( 1329 new_right = new(block()->zone()) HChange(
1321 right, Representation::Integer32(), false, false, false); 1330 right, Representation::Integer32(), false, false);
1322 HChange::cast(new_right)->InsertBefore(this); 1331 HChange::cast(new_right)->InsertBefore(this);
1323 } 1332 }
1324 1333
1325 // Return if left or right are not optimizable. 1334 // Return if left or right are not optimizable.
1326 if ((new_left == NULL) || (new_right == NULL)) return this; 1335 if ((new_left == NULL) || (new_right == NULL)) return this;
1327 1336
1328 // Insert the new values in the graph. 1337 // Insert the new values in the graph.
1329 if (new_left->IsInstruction() && 1338 if (new_left->IsInstruction() &&
1330 !HInstruction::cast(new_left)->IsLinked()) { 1339 !HInstruction::cast(new_left)->IsLinked()) {
1331 HInstruction::cast(new_left)->InsertBefore(this); 1340 HInstruction::cast(new_left)->InsertBefore(this);
1332 } 1341 }
1333 if (new_right->IsInstruction() && 1342 if (new_right->IsInstruction() &&
1334 !HInstruction::cast(new_right)->IsLinked()) { 1343 !HInstruction::cast(new_right)->IsLinked()) {
1335 HInstruction::cast(new_right)->InsertBefore(this); 1344 HInstruction::cast(new_right)->InsertBefore(this);
1336 } 1345 }
1337 HMathFloorOfDiv* instr = 1346 HMathFloorOfDiv* instr =
1338 HMathFloorOfDiv::New(block()->zone(), context(), new_left, new_right); 1347 HMathFloorOfDiv::New(block()->zone(), context(), new_left, new_right);
1339 // Replace this HMathFloor instruction by the new HMathFloorOfDiv. 1348 // Replace this HMathFloor instruction by the new HMathFloorOfDiv.
1340 instr->InsertBefore(this); 1349 instr->InsertBefore(this);
1341 ReplaceAllUsesWith(instr); 1350 ReplaceAllUsesWith(instr);
1342 Kill(); 1351 Kill();
1343 // We know the division had no other uses than this HMathFloor. Delete it. 1352 // We know the division had no other uses than this HMathFloor. Delete it.
1344 // Dead code elimination will deal with |left| and |right| if 1353 // Dead code elimination will deal with |left| and |right| if
1345 // appropriate. 1354 // appropriate.
1346 hdiv->DeleteAndReplaceWith(NULL); 1355 hdiv->DeleteAndReplaceWith(NULL);
1347 1356
1348 // Return NULL to remove this instruction from the graph. 1357 // Return NULL to remove this instruction from the graph.
1349 return NULL; 1358 return NULL;
1350 } 1359 }
1351 #endif
1352 } 1360 }
1353 return this; 1361 return this;
1354 } 1362 }
1355 1363
1356 1364
1357 HValue* HCheckInstanceType::Canonicalize() { 1365 HValue* HCheckInstanceType::Canonicalize() {
1358 if (check_ == IS_STRING && value()->type().IsString()) { 1366 if (check_ == IS_STRING && value()->type().IsString()) {
1359 return value(); 1367 return value();
1360 } 1368 }
1361 1369
(...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after
2772 2780
2773 2781
2774 void HCompareObjectEqAndBranch::PrintDataTo(StringStream* stream) { 2782 void HCompareObjectEqAndBranch::PrintDataTo(StringStream* stream) {
2775 left()->PrintNameTo(stream); 2783 left()->PrintNameTo(stream);
2776 stream->Add(" "); 2784 stream->Add(" ");
2777 right()->PrintNameTo(stream); 2785 right()->PrintNameTo(stream);
2778 HControlInstruction::PrintDataTo(stream); 2786 HControlInstruction::PrintDataTo(stream);
2779 } 2787 }
2780 2788
2781 2789
2790 void HCompareHoleAndBranch::PrintDataTo(StringStream* stream) {
2791 object()->PrintNameTo(stream);
2792 HControlInstruction::PrintDataTo(stream);
2793 }
2794
2795
2796 void HCompareHoleAndBranch::InferRepresentation(
2797 HInferRepresentationPhase* h_infer) {
2798 ChangeRepresentation(object()->representation());
2799 }
2800
2801
2782 void HGoto::PrintDataTo(StringStream* stream) { 2802 void HGoto::PrintDataTo(StringStream* stream) {
2783 stream->Add("B%d", SuccessorAt(0)->block_id()); 2803 stream->Add("B%d", SuccessorAt(0)->block_id());
2784 } 2804 }
2785 2805
2786 2806
2787 void HCompareNumericAndBranch::InferRepresentation( 2807 void HCompareNumericAndBranch::InferRepresentation(
2788 HInferRepresentationPhase* h_infer) { 2808 HInferRepresentationPhase* h_infer) {
2789 Representation left_rep = left()->representation(); 2809 Representation left_rep = left()->representation();
2790 Representation right_rep = right()->representation(); 2810 Representation right_rep = right()->representation();
2791 Representation observed_left = observed_input_representation(0); 2811 Representation observed_left = observed_input_representation(0);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 void HLoadNamedField::PrintDataTo(StringStream* stream) { 2851 void HLoadNamedField::PrintDataTo(StringStream* stream) {
2832 object()->PrintNameTo(stream); 2852 object()->PrintNameTo(stream);
2833 access_.PrintTo(stream); 2853 access_.PrintTo(stream);
2834 if (HasTypeCheck()) { 2854 if (HasTypeCheck()) {
2835 stream->Add(" "); 2855 stream->Add(" ");
2836 typecheck()->PrintNameTo(stream); 2856 typecheck()->PrintNameTo(stream);
2837 } 2857 }
2838 } 2858 }
2839 2859
2840 2860
2841 // Returns true if an instance of this map can never find a property with this
2842 // name in its prototype chain. This means all prototypes up to the top are
2843 // fast and don't have the name in them. It would be good if we could optimize
2844 // polymorphic loads where the property is sometimes found in the prototype
2845 // chain.
2846 static bool PrototypeChainCanNeverResolve(
2847 Handle<Map> map, Handle<String> name) {
2848 Isolate* isolate = map->GetIsolate();
2849 Object* current = map->prototype();
2850 while (current != isolate->heap()->null_value()) {
2851 if (current->IsJSGlobalProxy() ||
2852 current->IsGlobalObject() ||
2853 !current->IsJSObject() ||
2854 JSObject::cast(current)->map()->has_named_interceptor() ||
2855 JSObject::cast(current)->IsAccessCheckNeeded() ||
2856 !JSObject::cast(current)->HasFastProperties()) {
2857 return false;
2858 }
2859
2860 LookupResult lookup(isolate);
2861 Map* map = JSObject::cast(current)->map();
2862 map->LookupDescriptor(NULL, *name, &lookup);
2863 if (lookup.IsFound()) return false;
2864 if (!lookup.IsCacheable()) return false;
2865 current = JSObject::cast(current)->GetPrototype();
2866 }
2867 return true;
2868 }
2869
2870
2871 HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
2872 HValue* object,
2873 SmallMapList* types,
2874 Handle<String> name,
2875 Zone* zone)
2876 : types_(Min(types->length(), kMaxLoadPolymorphism), zone),
2877 name_(name),
2878 types_unique_ids_(0, zone),
2879 name_unique_id_(),
2880 need_generic_(false) {
2881 SetOperandAt(0, context);
2882 SetOperandAt(1, object);
2883 set_representation(Representation::Tagged());
2884 SetGVNFlag(kDependsOnMaps);
2885 SmallMapList negative_lookups;
2886 for (int i = 0;
2887 i < types->length() && types_.length() < kMaxLoadPolymorphism;
2888 ++i) {
2889 Handle<Map> map = types->at(i);
2890 // Deprecated maps are updated to the current map in the type oracle.
2891 ASSERT(!map->is_deprecated());
2892 LookupResult lookup(map->GetIsolate());
2893 map->LookupDescriptor(NULL, *name, &lookup);
2894 if (lookup.IsFound()) {
2895 switch (lookup.type()) {
2896 case FIELD: {
2897 int index = lookup.GetLocalFieldIndexFromMap(*map);
2898 if (index < 0) {
2899 SetGVNFlag(kDependsOnInobjectFields);
2900 } else {
2901 SetGVNFlag(kDependsOnBackingStoreFields);
2902 }
2903 if (FLAG_track_double_fields &&
2904 lookup.representation().IsDouble()) {
2905 // Since the value needs to be boxed, use a generic handler for
2906 // loading doubles.
2907 continue;
2908 }
2909 types_.Add(types->at(i), zone);
2910 break;
2911 }
2912 case CONSTANT:
2913 types_.Add(types->at(i), zone);
2914 break;
2915 case CALLBACKS:
2916 break;
2917 case TRANSITION:
2918 case INTERCEPTOR:
2919 case NONEXISTENT:
2920 case NORMAL:
2921 case HANDLER:
2922 UNREACHABLE();
2923 break;
2924 }
2925 } else if (lookup.IsCacheable() &&
2926 // For dicts the lookup on the map will fail, but the object may
2927 // contain the property so we cannot generate a negative lookup
2928 // (which would just be a map check and return undefined).
2929 !map->is_dictionary_map() &&
2930 !map->has_named_interceptor() &&
2931 PrototypeChainCanNeverResolve(map, name)) {
2932 negative_lookups.Add(types->at(i), zone);
2933 }
2934 }
2935
2936 bool need_generic =
2937 (types->length() != negative_lookups.length() + types_.length());
2938 if (!need_generic && FLAG_deoptimize_uncommon_cases) {
2939 SetFlag(kUseGVN);
2940 for (int i = 0; i < negative_lookups.length(); i++) {
2941 types_.Add(negative_lookups.at(i), zone);
2942 }
2943 } else {
2944 // We don't have an easy way to handle both a call (to the generic stub) and
2945 // a deopt in the same hydrogen instruction, so in this case we don't add
2946 // the negative lookups which can deopt - just let the generic stub handle
2947 // them.
2948 SetAllSideEffects();
2949 need_generic_ = true;
2950 }
2951 }
2952
2953
2954 HCheckMaps* HCheckMaps::New(Zone* zone, 2861 HCheckMaps* HCheckMaps::New(Zone* zone,
2955 HValue* context, 2862 HValue* context,
2956 HValue* value, 2863 HValue* value,
2957 Handle<Map> map, 2864 Handle<Map> map,
2958 CompilationInfo* info, 2865 CompilationInfo* info,
2959 HValue* typecheck) { 2866 HValue* typecheck) {
2960 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); 2867 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
2961 check_map->map_set_.Add(map, zone); 2868 check_map->Add(map, zone);
2962 check_map->has_migration_target_ = map->is_migration_target();
2963 if (map->CanOmitMapChecks() && 2869 if (map->CanOmitMapChecks() &&
2964 value->IsConstant() && 2870 value->IsConstant() &&
2965 HConstant::cast(value)->InstanceOf(map)) { 2871 HConstant::cast(value)->InstanceOf(map)) {
2966 check_map->omit(info); 2872 check_map->omit(info);
2967 } 2873 }
2968 return check_map; 2874 return check_map;
2969 } 2875 }
2970 2876
2971 2877
2972 void HCheckMaps::FinalizeUniqueValueId() { 2878 void HCheckMaps::FinalizeUniqueValueId() {
2973 if (!map_unique_ids_.is_empty()) return; 2879 if (!map_unique_ids_.is_empty()) return;
2974 Zone* zone = block()->zone(); 2880 Zone* zone = block()->zone();
2975 map_unique_ids_.Initialize(map_set_.length(), zone); 2881 map_unique_ids_.Initialize(map_set_.length(), zone);
2976 for (int i = 0; i < map_set_.length(); i++) { 2882 for (int i = 0; i < map_set_.length(); i++) {
2977 map_unique_ids_.Add(UniqueValueId(map_set_.at(i)), zone); 2883 map_unique_ids_.Add(UniqueValueId(map_set_.at(i)), zone);
2978 } 2884 }
2979 } 2885 }
2980 2886
2981 2887
2982 void HLoadNamedFieldPolymorphic::FinalizeUniqueValueId() {
2983 if (!types_unique_ids_.is_empty()) return;
2984 Zone* zone = block()->zone();
2985 types_unique_ids_.Initialize(types_.length(), zone);
2986 for (int i = 0; i < types_.length(); i++) {
2987 types_unique_ids_.Add(UniqueValueId(types_.at(i)), zone);
2988 }
2989 name_unique_id_ = UniqueValueId(name_);
2990 }
2991
2992
2993 bool HLoadNamedFieldPolymorphic::DataEquals(HValue* value) {
2994 ASSERT_EQ(types_.length(), types_unique_ids_.length());
2995 HLoadNamedFieldPolymorphic* other = HLoadNamedFieldPolymorphic::cast(value);
2996 if (name_unique_id_ != other->name_unique_id_) return false;
2997 if (types_unique_ids_.length() != other->types_unique_ids_.length()) {
2998 return false;
2999 }
3000 if (need_generic_ != other->need_generic_) return false;
3001 for (int i = 0; i < types_unique_ids_.length(); i++) {
3002 bool found = false;
3003 for (int j = 0; j < types_unique_ids_.length(); j++) {
3004 if (types_unique_ids_.at(j) == other->types_unique_ids_.at(i)) {
3005 found = true;
3006 break;
3007 }
3008 }
3009 if (!found) return false;
3010 }
3011 return true;
3012 }
3013
3014
3015 void HLoadNamedFieldPolymorphic::PrintDataTo(StringStream* stream) {
3016 object()->PrintNameTo(stream);
3017 stream->Add(".");
3018 stream->Add(*String::cast(*name())->ToCString());
3019 }
3020
3021
3022 void HLoadNamedGeneric::PrintDataTo(StringStream* stream) { 2888 void HLoadNamedGeneric::PrintDataTo(StringStream* stream) {
3023 object()->PrintNameTo(stream); 2889 object()->PrintNameTo(stream);
3024 stream->Add("."); 2890 stream->Add(".");
3025 stream->Add(*String::cast(*name())->ToCString()); 2891 stream->Add(*String::cast(*name())->ToCString());
3026 } 2892 }
3027 2893
3028 2894
3029 void HLoadKeyed::PrintDataTo(StringStream* stream) { 2895 void HLoadKeyed::PrintDataTo(StringStream* stream) {
3030 if (!is_external()) { 2896 if (!is_external()) {
3031 elements()->PrintNameTo(stream); 2897 elements()->PrintNameTo(stream);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3084 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 2950 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
3085 HValue* use = it.value(); 2951 HValue* use = it.value();
3086 if (!use->IsChange()) return false; 2952 if (!use->IsChange()) return false;
3087 } 2953 }
3088 2954
3089 return true; 2955 return true;
3090 } 2956 }
3091 2957
3092 2958
3093 bool HLoadKeyed::AllUsesCanTreatHoleAsNaN() const { 2959 bool HLoadKeyed::AllUsesCanTreatHoleAsNaN() const {
3094 if (!IsFastDoubleElementsKind(elements_kind())) { 2960 return IsFastDoubleElementsKind(elements_kind()) &&
3095 return false; 2961 CheckUsesForFlag(HValue::kAllowUndefinedAsNaN);
3096 }
3097
3098 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
3099 HValue* use = it.value();
3100 if (!use->CheckFlag(HValue::kAllowUndefinedAsNaN)) {
3101 return false;
3102 }
3103 }
3104
3105 return true;
3106 } 2962 }
3107 2963
3108 2964
3109 bool HLoadKeyed::RequiresHoleCheck() const { 2965 bool HLoadKeyed::RequiresHoleCheck() const {
3110 if (IsFastPackedElementsKind(elements_kind())) { 2966 if (IsFastPackedElementsKind(elements_kind())) {
3111 return false; 2967 return false;
3112 } 2968 }
3113 2969
3114 if (IsExternalArrayElementsKind(elements_kind())) { 2970 if (IsExternalArrayElementsKind(elements_kind())) {
3115 return false; 2971 return false;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3224 3080
3225 void HTransitionElementsKind::PrintDataTo(StringStream* stream) { 3081 void HTransitionElementsKind::PrintDataTo(StringStream* stream) {
3226 object()->PrintNameTo(stream); 3082 object()->PrintNameTo(stream);
3227 ElementsKind from_kind = original_map()->elements_kind(); 3083 ElementsKind from_kind = original_map()->elements_kind();
3228 ElementsKind to_kind = transitioned_map()->elements_kind(); 3084 ElementsKind to_kind = transitioned_map()->elements_kind();
3229 stream->Add(" %p [%s] -> %p [%s]", 3085 stream->Add(" %p [%s] -> %p [%s]",
3230 *original_map(), 3086 *original_map(),
3231 ElementsAccessor::ForKind(from_kind)->name(), 3087 ElementsAccessor::ForKind(from_kind)->name(),
3232 *transitioned_map(), 3088 *transitioned_map(),
3233 ElementsAccessor::ForKind(to_kind)->name()); 3089 ElementsAccessor::ForKind(to_kind)->name());
3090 if (IsSimpleMapChangeTransition(from_kind, to_kind)) stream->Add(" (simple)");
3234 } 3091 }
3235 3092
3236 3093
3237 void HLoadGlobalCell::PrintDataTo(StringStream* stream) { 3094 void HLoadGlobalCell::PrintDataTo(StringStream* stream) {
3238 stream->Add("[%p]", *cell()); 3095 stream->Add("[%p]", *cell());
3239 if (!details_.IsDontDelete()) stream->Add(" (deleteable)"); 3096 if (!details_.IsDontDelete()) stream->Add(" (deleteable)");
3240 if (details_.IsReadOnly()) stream->Add(" (read-only)"); 3097 if (details_.IsReadOnly()) stream->Add(" (read-only)");
3241 } 3098 }
3242 3099
3243 3100
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3312 if (from().IsDouble() && to().IsTagged()) return HType::HeapNumber(); 3169 if (from().IsDouble() && to().IsTagged()) return HType::HeapNumber();
3313 return type(); 3170 return type();
3314 } 3171 }
3315 3172
3316 3173
3317 Representation HUnaryMathOperation::RepresentationFromInputs() { 3174 Representation HUnaryMathOperation::RepresentationFromInputs() {
3318 Representation rep = representation(); 3175 Representation rep = representation();
3319 // If any of the actual input representation is more general than what we 3176 // If any of the actual input representation is more general than what we
3320 // have so far but not Tagged, use that representation instead. 3177 // have so far but not Tagged, use that representation instead.
3321 Representation input_rep = value()->representation(); 3178 Representation input_rep = value()->representation();
3322 if (!input_rep.IsTagged()) rep = rep.generalize(input_rep); 3179 if (!input_rep.IsTagged()) {
3180 rep = rep.generalize(input_rep);
3181 }
3323 return rep; 3182 return rep;
3324 } 3183 }
3325 3184
3326 3185
3327 void HAllocate::HandleSideEffectDominator(GVNFlag side_effect, 3186 void HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
3328 HValue* dominator) { 3187 HValue* dominator) {
3329 ASSERT(side_effect == kChangesNewSpacePromotion); 3188 ASSERT(side_effect == kChangesNewSpacePromotion);
3330 if (!FLAG_use_allocation_folding) return; 3189 if (!FLAG_use_allocation_folding) return;
3331 3190
3332 // Try to fold allocations together with their dominating allocations. 3191 // Try to fold allocations together with their dominating allocations.
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
3868 for (int i = 0; i < OperandCount(); ++i) { 3727 for (int i = 0; i < OperandCount(); ++i) {
3869 HConstant* operand = HConstant::cast(OperandAt(i)); 3728 HConstant* operand = HConstant::cast(OperandAt(i));
3870 if (operand->HasInteger32Value()) { 3729 if (operand->HasInteger32Value()) {
3871 continue; 3730 continue;
3872 } else if (operand->HasDoubleValue()) { 3731 } else if (operand->HasDoubleValue()) {
3873 HConstant* integer_input = 3732 HConstant* integer_input =
3874 HConstant::New(graph->zone(), graph->GetInvalidContext(), 3733 HConstant::New(graph->zone(), graph->GetInvalidContext(),
3875 DoubleToInt32(operand->DoubleValue())); 3734 DoubleToInt32(operand->DoubleValue()));
3876 integer_input->InsertAfter(operand); 3735 integer_input->InsertAfter(operand);
3877 SetOperandAt(i, integer_input); 3736 SetOperandAt(i, integer_input);
3878 } else if (operand == graph->GetConstantTrue()) { 3737 } else if (operand->HasBooleanValue()) {
3879 SetOperandAt(i, graph->GetConstant1()); 3738 SetOperandAt(i, operand->BooleanValue() ? graph->GetConstant1()
3880 } else { 3739 : graph->GetConstant0());
3881 // This catches |false|, |undefined|, strings and objects. 3740 } else if (operand->ImmortalImmovable()) {
3882 SetOperandAt(i, graph->GetConstant0()); 3741 SetOperandAt(i, graph->GetConstant0());
3883 } 3742 }
3884 } 3743 }
3885 // Overwrite observed input representations because they are likely Tagged. 3744 // Overwrite observed input representations because they are likely Tagged.
3886 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 3745 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
3887 HValue* use = it.value(); 3746 HValue* use = it.value();
3888 if (use->IsBinaryOperation()) { 3747 if (use->IsBinaryOperation()) {
3889 HBinaryOperation::cast(use)->set_observed_input_representation( 3748 HBinaryOperation::cast(use)->set_observed_input_representation(
3890 it.index(), Representation::Smi()); 3749 it.index(), Representation::Smi());
3891 } 3750 }
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
4141 break; 4000 break;
4142 case kExternalMemory: 4001 case kExternalMemory:
4143 stream->Add("[external-memory]"); 4002 stream->Add("[external-memory]");
4144 break; 4003 break;
4145 } 4004 }
4146 4005
4147 stream->Add("@%d", offset()); 4006 stream->Add("@%d", offset());
4148 } 4007 }
4149 4008
4150 } } // namespace v8::internal 4009 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/hydrogen-mark-deoptimize.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698