| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/code_descriptors.h" | 10 #include "vm/code_descriptors.h" |
| (...skipping 2861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2872 return TypedData::length_offset(); | 2872 return TypedData::length_offset(); |
| 2873 case MethodRecognizer::kGrowableArrayLength: | 2873 case MethodRecognizer::kGrowableArrayLength: |
| 2874 return GrowableObjectArray::length_offset(); | 2874 return GrowableObjectArray::length_offset(); |
| 2875 default: | 2875 default: |
| 2876 UNREACHABLE(); | 2876 UNREACHABLE(); |
| 2877 return 0; | 2877 return 0; |
| 2878 } | 2878 } |
| 2879 } | 2879 } |
| 2880 | 2880 |
| 2881 | 2881 |
| 2882 static LoadLocalInstr* BuildLoadThisVar(LocalScope* scope) { |
| 2883 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), |
| 2884 true); // Test only. |
| 2885 return new LoadLocalInstr(*receiver_var); |
| 2886 } |
| 2887 |
| 2888 |
| 2882 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { | 2889 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| 2883 const Function& function = owner()->parsed_function()->function(); | 2890 const Function& function = owner()->parsed_function()->function(); |
| 2884 if (!function.IsClosureFunction()) { | 2891 if (!function.IsClosureFunction()) { |
| 2885 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); | 2892 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); |
| 2886 switch (kind) { | 2893 switch (kind) { |
| 2887 case MethodRecognizer::kStringBaseLength: { | 2894 case MethodRecognizer::kStringBaseLength: |
| 2888 LocalVariable* receiver_var = | 2895 case MethodRecognizer::kStringBaseIsEmpty: { |
| 2889 node->scope()->LookupVariable(Symbols::This(), | 2896 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 2890 true); // Test only. | |
| 2891 Value* receiver = Bind(new LoadLocalInstr(*receiver_var)); | |
| 2892 // Treat length loads as mutable (i.e. affected by side effects) to | 2897 // Treat length loads as mutable (i.e. affected by side effects) to |
| 2893 // avoid hoisting them since we can't hoist the preceding class-check. | 2898 // avoid hoisting them since we can't hoist the preceding class-check. |
| 2894 // This is because of externalization of strings that affects their | 2899 // This is because of externalization of strings that affects their |
| 2895 // class-id. | 2900 // class-id. |
| 2896 const bool is_immutable = false; | 2901 const bool is_immutable = false; |
| 2897 LoadFieldInstr* load = new LoadFieldInstr( | 2902 LoadFieldInstr* load = new LoadFieldInstr( |
| 2898 receiver, | 2903 receiver, |
| 2899 String::length_offset(), | 2904 String::length_offset(), |
| 2900 Type::ZoneHandle(Type::SmiType()), | 2905 Type::ZoneHandle(Type::SmiType()), |
| 2901 is_immutable); | 2906 is_immutable); |
| 2902 load->set_result_cid(kSmiCid); | 2907 load->set_result_cid(kSmiCid); |
| 2903 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); | 2908 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); |
| 2904 return ReturnDefinition(load); | 2909 if (kind == MethodRecognizer::kStringBaseLength) { |
| 2910 return ReturnDefinition(load); |
| 2911 } |
| 2912 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); |
| 2913 Value* zero_val = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(0)))); |
| 2914 Value* load_val = Bind(load); |
| 2915 StrictCompareInstr* compare = |
| 2916 new StrictCompareInstr(node->token_pos(), |
| 2917 Token::kEQ_STRICT, |
| 2918 load_val, |
| 2919 zero_val); |
| 2920 return ReturnDefinition(compare); |
| 2905 } | 2921 } |
| 2906 case MethodRecognizer::kGrowableArrayLength: | 2922 case MethodRecognizer::kGrowableArrayLength: |
| 2907 case MethodRecognizer::kObjectArrayLength: | 2923 case MethodRecognizer::kObjectArrayLength: |
| 2908 case MethodRecognizer::kImmutableArrayLength: | 2924 case MethodRecognizer::kImmutableArrayLength: |
| 2909 case MethodRecognizer::kTypedDataLength: { | 2925 case MethodRecognizer::kTypedDataLength: { |
| 2910 LocalVariable* receiver_var = | 2926 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 2911 node->scope()->LookupVariable(Symbols::This(), | |
| 2912 true); // Test only. | |
| 2913 Value* receiver = Bind(new LoadLocalInstr(*receiver_var)); | |
| 2914 const bool is_immutable = | 2927 const bool is_immutable = |
| 2915 (kind != MethodRecognizer::kGrowableArrayLength); | 2928 (kind != MethodRecognizer::kGrowableArrayLength); |
| 2916 LoadFieldInstr* load = new LoadFieldInstr( | 2929 LoadFieldInstr* load = new LoadFieldInstr( |
| 2917 receiver, | 2930 receiver, |
| 2918 OffsetForLengthGetter(kind), | 2931 OffsetForLengthGetter(kind), |
| 2919 Type::ZoneHandle(Type::SmiType()), | 2932 Type::ZoneHandle(Type::SmiType()), |
| 2920 is_immutable); | 2933 is_immutable); |
| 2921 load->set_result_cid(kSmiCid); | 2934 load->set_result_cid(kSmiCid); |
| 2922 load->set_recognized_kind(kind); | 2935 load->set_recognized_kind(kind); |
| 2923 return ReturnDefinition(load); | 2936 return ReturnDefinition(load); |
| 2924 } | 2937 } |
| 2938 case MethodRecognizer::kObjectCid: { |
| 2939 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 2940 LoadClassIdInstr* load = new LoadClassIdInstr(receiver); |
| 2941 return ReturnDefinition(load); |
| 2942 } |
| 2943 case MethodRecognizer::kGrowableArrayCapacity: { |
| 2944 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 2945 LoadFieldInstr* data_load = new LoadFieldInstr( |
| 2946 receiver, |
| 2947 Array::data_offset(), |
| 2948 Type::ZoneHandle(Type::DynamicType())); |
| 2949 data_load->set_result_cid(kArrayCid); |
| 2950 Value* data = Bind(data_load); |
| 2951 LoadFieldInstr* length_load = new LoadFieldInstr( |
| 2952 data, |
| 2953 Array::length_offset(), |
| 2954 Type::ZoneHandle(Type::SmiType())); |
| 2955 length_load->set_result_cid(kSmiCid); |
| 2956 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); |
| 2957 return ReturnDefinition(length_load); |
| 2958 } |
| 2925 default: | 2959 default: |
| 2926 break; | 2960 break; |
| 2927 } | 2961 } |
| 2928 } | 2962 } |
| 2929 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); | 2963 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); |
| 2930 function.set_is_optimizable(false); | 2964 function.set_is_optimizable(false); |
| 2931 NativeCallInstr* native_call = new NativeCallInstr(node); | 2965 NativeCallInstr* native_call = new NativeCallInstr(node); |
| 2932 ReturnDefinition(native_call); | 2966 ReturnDefinition(native_call); |
| 2933 } | 2967 } |
| 2934 | 2968 |
| (...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3768 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3802 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3769 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3803 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3770 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3804 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3771 const Error& error = Error::Handle( | 3805 const Error& error = Error::Handle( |
| 3772 LanguageError::New(String::Handle(String::New(chars)))); | 3806 LanguageError::New(String::Handle(String::New(chars)))); |
| 3773 Isolate::Current()->long_jump_base()->Jump(1, error); | 3807 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3774 } | 3808 } |
| 3775 | 3809 |
| 3776 | 3810 |
| 3777 } // namespace dart | 3811 } // namespace dart |
| OLD | NEW |