| 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/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1969 arguments->Add(push_ctor_arg); | 1969 arguments->Add(push_ctor_arg); |
| 1970 | 1970 |
| 1971 BuildPushArguments(*node->arguments(), arguments); | 1971 BuildPushArguments(*node->arguments(), arguments); |
| 1972 Do(new StaticCallInstr(node->token_pos(), | 1972 Do(new StaticCallInstr(node->token_pos(), |
| 1973 node->constructor(), | 1973 node->constructor(), |
| 1974 node->arguments()->names(), | 1974 node->arguments()->names(), |
| 1975 arguments)); | 1975 arguments)); |
| 1976 } | 1976 } |
| 1977 | 1977 |
| 1978 | 1978 |
| 1979 // List of recognized factories in core lib (factories with known result-cid): | 1979 // List of recognized list factories in core lib: |
| 1980 // (factory-name-symbol, result-cid, fingerprint). | 1980 // (factory-name-symbol, result-cid, fingerprint). |
| 1981 #define RECOGNIZED_FACTORY_LIST(V) \ | 1981 // TODO(srdjan): Store the values in the snapshot instead. |
| 1982 V(ObjectArrayDot, kArrayCid, 97987288) \ | 1982 // TODO(srdjan): Add Float32x4List. |
| 1983 #define RECOGNIZED_LIST_FACTORY_LIST(V) \ |
| 1984 V(ObjectArrayFactory, kArrayCid, 97987288) \ |
| 1983 V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 816132033) \ | 1985 V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 816132033) \ |
| 1984 V(GrowableObjectArrayDot, kGrowableObjectArrayCid, 1896741574) \ | 1986 V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 1896741574) \ |
| 1987 V(Int8ListFactory, kInt8ArrayCid, 817410959) \ |
| 1988 V(Uint8ListFactory, kUint8ArrayCid, 220896178) \ |
| 1989 V(Uint8ClampedListFactory, kUint8ClampedArrayCid, 422034060) \ |
| 1990 V(Int16ListFactory, kInt16ArrayCid, 214246025) \ |
| 1991 V(Uint16ListFactory, kUint16ArrayCid, 137929963) \ |
| 1992 V(Int32ListFactory, kInt32ArrayCid, 1977571010) \ |
| 1993 V(Uint32ListFactory, kUint32ArrayCid, 407638944) \ |
| 1994 V(Int64ListFactory, kInt64ArrayCid, 885130273) \ |
| 1995 V(Uint64ListFactory, kUint64ArrayCid, 1471017221) \ |
| 1996 V(Float64ListFactory, kFloat64ArrayCid, 1037441059) \ |
| 1997 V(Float32ListFactory, kFloat32ArrayCid, 2035252095) \ |
| 1985 | 1998 |
| 1986 | 1999 |
| 1987 // Class that recognizes factories and returns corresponding result cid. | 2000 // Class that recognizes factories and returns corresponding result cid. |
| 1988 class FactoryRecognizer : public AllStatic { | 2001 class FactoryRecognizer : public AllStatic { |
| 1989 public: | 2002 public: |
| 1990 // Return kDynamicCid if factory is not recognized. | 2003 // Return kDynamicCid if factory is not recognized. |
| 1991 static intptr_t ResultCid(const Function& factory) { | 2004 static intptr_t ResultCid(const Function& factory) { |
| 1992 ASSERT(factory.IsFactory()); | 2005 ASSERT(factory.IsFactory()); |
| 1993 const Class& function_class = Class::Handle(factory.Owner()); | 2006 const Class& function_class = Class::Handle(factory.Owner()); |
| 1994 const Library& lib = Library::Handle(function_class.library()); | 2007 const Library& lib = Library::Handle(function_class.library()); |
| 1995 if (lib.raw() != Library::CoreLibrary()) { | 2008 ASSERT((lib.raw() == Library::CoreLibrary()) || |
| 1996 // Only core library factories recognized. | 2009 (lib.raw() == Library::ScalarlistLibrary())); |
| 1997 return kDynamicCid; | |
| 1998 } | |
| 1999 const String& factory_name = String::Handle(factory.name()); | 2010 const String& factory_name = String::Handle(factory.name()); |
| 2000 #define RECOGNIZE_FACTORY(test_factory_symbol, cid, fp) \ | 2011 #define RECOGNIZE_FACTORY(test_factory_symbol, cid, fp) \ |
| 2001 if (String::EqualsIgnoringPrivateKey( \ | 2012 if (String::EqualsIgnoringPrivateKey( \ |
| 2002 factory_name, Symbols::test_factory_symbol())) { \ | 2013 factory_name, Symbols::test_factory_symbol())) { \ |
| 2003 ASSERT(factory.CheckSourceFingerprint(fp)); \ | 2014 ASSERT(factory.CheckSourceFingerprint(fp)); \ |
| 2004 return cid; \ | 2015 return cid; \ |
| 2005 } \ | 2016 } \ |
| 2006 | 2017 |
| 2007 RECOGNIZED_FACTORY_LIST(RECOGNIZE_FACTORY); | 2018 RECOGNIZED_LIST_FACTORY_LIST(RECOGNIZE_FACTORY); |
| 2008 #undef RECOGNIZE_FACTORY | 2019 #undef RECOGNIZE_FACTORY |
| 2009 | 2020 |
| 2010 return kDynamicCid; | 2021 return kDynamicCid; |
| 2011 } | 2022 } |
| 2012 }; | 2023 }; |
| 2013 | 2024 |
| 2014 | 2025 |
| 2015 static intptr_t GetResultCidOfConstructor(ConstructorCallNode* node) { | 2026 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) { |
| 2016 const Function& function = node->constructor(); | 2027 const Function& function = node->constructor(); |
| 2017 const Class& function_class = Class::Handle(function.Owner()); | 2028 const Class& function_class = Class::Handle(function.Owner()); |
| 2018 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | |
| 2019 | 2029 |
| 2020 if (function_class.library() != core_lib.raw()) { | 2030 if ((function_class.library() != Library::CoreLibrary()) && |
| 2031 (function_class.library() != Library::ScalarlistLibrary())) { |
| 2021 return kDynamicCid; | 2032 return kDynamicCid; |
| 2022 } | 2033 } |
| 2023 | 2034 |
| 2024 if (node->constructor().IsFactory()) { | 2035 if (node->constructor().IsFactory()) { |
| 2025 if ((function_class.Name() == Symbols::List().raw()) && | 2036 if ((function_class.Name() == Symbols::List().raw()) && |
| 2026 (function.name() == Symbols::ListFactory().raw())) { | 2037 (function.name() == Symbols::ListFactory().raw())) { |
| 2027 // Special recognition of 'new List()' vs 'new List(n)'. | 2038 // Special recognition of 'new List()' vs 'new List(n)'. |
| 2028 if (node->arguments()->length() == 0) { | 2039 if (node->arguments()->length() == 0) { |
| 2029 return kGrowableObjectArrayCid; | 2040 return kGrowableObjectArrayCid; |
| 2030 } | 2041 } |
| 2031 return kArrayCid; | 2042 return kArrayCid; |
| 2032 } | 2043 } |
| 2033 return FactoryRecognizer::ResultCid(function); | 2044 return FactoryRecognizer::ResultCid(function); |
| 2034 } | 2045 } |
| 2035 return kDynamicCid; // Result cid not known. | 2046 return kDynamicCid; // Not a known list constructor. |
| 2036 } | 2047 } |
| 2037 | 2048 |
| 2038 | 2049 |
| 2039 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 2050 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 2040 if (node->constructor().IsFactory()) { | 2051 if (node->constructor().IsFactory()) { |
| 2041 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2052 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2042 new ZoneGrowableArray<PushArgumentInstr*>(); | 2053 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 2043 PushArgumentInstr* push_type_arguments = PushArgument( | 2054 PushArgumentInstr* push_type_arguments = PushArgument( |
| 2044 BuildInstantiatedTypeArguments(node->token_pos(), | 2055 BuildInstantiatedTypeArguments(node->token_pos(), |
| 2045 node->type_arguments())); | 2056 node->type_arguments())); |
| 2046 arguments->Add(push_type_arguments); | 2057 arguments->Add(push_type_arguments); |
| 2047 ASSERT(arguments->length() == 1); | 2058 ASSERT(arguments->length() == 1); |
| 2048 BuildPushArguments(*node->arguments(), arguments); | 2059 BuildPushArguments(*node->arguments(), arguments); |
| 2049 StaticCallInstr* call = | 2060 StaticCallInstr* call = |
| 2050 new StaticCallInstr(node->token_pos(), | 2061 new StaticCallInstr(node->token_pos(), |
| 2051 node->constructor(), | 2062 node->constructor(), |
| 2052 node->arguments()->names(), | 2063 node->arguments()->names(), |
| 2053 arguments); | 2064 arguments); |
| 2054 // List factories return kArrayCid or kGrowableObjectArrayCid. | 2065 const intptr_t result_cid = GetResultCidOfListFactory(node); |
| 2055 const intptr_t result_cid = GetResultCidOfConstructor(node); | 2066 if (result_cid != kDynamicCid) { |
| 2056 call->set_result_cid(result_cid); | 2067 call->set_result_cid(result_cid); |
| 2057 call->set_is_known_constructor(result_cid != kDynamicCid); | 2068 call->set_is_known_list_constructor(true); |
| 2069 // Recognized fixed length array factory must have two arguments: |
| 2070 // (0) type-arguments, (1) length. |
| 2071 ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) || |
| 2072 arguments->length() == 2); |
| 2073 } |
| 2058 ReturnDefinition(call); | 2074 ReturnDefinition(call); |
| 2059 return; | 2075 return; |
| 2060 } | 2076 } |
| 2061 // t_n contains the allocated and initialized object. | 2077 // t_n contains the allocated and initialized object. |
| 2062 // t_n <- AllocateObject(class) | 2078 // t_n <- AllocateObject(class) |
| 2063 // t_n+1 <- ctor-arg | 2079 // t_n+1 <- ctor-arg |
| 2064 // t_n+2... <- constructor arguments start here | 2080 // t_n+2... <- constructor arguments start here |
| 2065 // StaticCall(constructor, t_n+1, t_n+2, ...) | 2081 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 2066 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 2082 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 2067 Value* allocated_value = BuildObjectAllocation(node); | 2083 Value* allocated_value = BuildObjectAllocation(node); |
| (...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3275 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3291 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3276 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3292 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3277 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3293 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3278 const Error& error = Error::Handle( | 3294 const Error& error = Error::Handle( |
| 3279 LanguageError::New(String::Handle(String::New(chars)))); | 3295 LanguageError::New(String::Handle(String::New(chars)))); |
| 3280 Isolate::Current()->long_jump_base()->Jump(1, error); | 3296 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3281 } | 3297 } |
| 3282 | 3298 |
| 3283 | 3299 |
| 3284 } // namespace dart | 3300 } // namespace dart |
| OLD | NEW |