| 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 "platform/assert.h" | 5 #include "platform/assert.h" |
| 6 #include "vm/assembler.h" | 6 #include "vm/assembler.h" |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| 11 #include "vm/object_store.h" | 11 #include "vm/object_store.h" |
| 12 #include "vm/simulator.h" |
| 12 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
| 13 #include "vm/unit_test.h" | 14 #include "vm/unit_test.h" |
| 14 | 15 |
| 15 namespace dart { | 16 namespace dart { |
| 16 | 17 |
| 17 TEST_CASE(Class) { | 18 TEST_CASE(Class) { |
| 18 // Allocate the class first. | 19 // Allocate the class first. |
| 19 const String& class_name = String::Handle(Symbols::New("MyClass")); | 20 const String& class_name = String::Handle(Symbols::New("MyClass")); |
| 20 const Script& script = Script::Handle(); | 21 const Script& script = Script::Handle(); |
| 21 const Class& cls = Class::Handle( | 22 const Class& cls = Class::Handle( |
| (...skipping 2207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2229 EXPECT(!str3.IsOneByteString()); | 2230 EXPECT(!str3.IsOneByteString()); |
| 2230 str3 = String::New("Steep and Deep!"); | 2231 str3 = String::New("Steep and Deep!"); |
| 2231 EXPECT(str3.IsString()); | 2232 EXPECT(str3.IsString()); |
| 2232 EXPECT(str3.IsOneByteString()); | 2233 EXPECT(str3.IsOneByteString()); |
| 2233 str3 = OneByteString::null(); | 2234 str3 = OneByteString::null(); |
| 2234 EXPECT(str3.IsString()); | 2235 EXPECT(str3.IsString()); |
| 2235 EXPECT(!str3.IsOneByteString()); | 2236 EXPECT(!str3.IsOneByteString()); |
| 2236 } | 2237 } |
| 2237 | 2238 |
| 2238 | 2239 |
| 2239 // only ia32 and x64 can run execution tests. | 2240 // Only ia32, x64, and arm can run execution tests. |
| 2240 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) | 2241 #if defined(TARGET_ARCH_IA32) || \ |
| 2242 defined(TARGET_ARCH_X64) || \ |
| 2243 defined(TARGET_ARCH_ARM) |
| 2241 | 2244 |
| 2242 static Function* CreateFunction(const char* name) { | 2245 static Function* CreateFunction(const char* name) { |
| 2243 const String& class_name = String::Handle(Symbols::New("ownerClass")); | 2246 const String& class_name = String::Handle(Symbols::New("ownerClass")); |
| 2244 const Script& script = Script::Handle(); | 2247 const Script& script = Script::Handle(); |
| 2245 const Class& owner_class = | 2248 const Class& owner_class = |
| 2246 Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex)); | 2249 Class::Handle(Class::New(class_name, script, Scanner::kDummyTokenIndex)); |
| 2247 const String& function_name = String::ZoneHandle(Symbols::New(name)); | 2250 const String& function_name = String::ZoneHandle(Symbols::New(name)); |
| 2248 Function& function = Function::ZoneHandle( | 2251 Function& function = Function::ZoneHandle( |
| 2249 Function::New(function_name, RawFunction::kRegularFunction, | 2252 Function::New(function_name, RawFunction::kRegularFunction, |
| 2250 true, false, false, false, owner_class, 0)); | 2253 true, false, false, false, owner_class, 0)); |
| 2251 return &function; | 2254 return &function; |
| 2252 } | 2255 } |
| 2253 | 2256 |
| 2254 // Test for Code and Instruction object creation. | 2257 // Test for Code and Instruction object creation. |
| 2255 TEST_CASE(Code) { | 2258 TEST_CASE(Code) { |
| 2256 extern void GenerateIncrement(Assembler* assembler); | 2259 extern void GenerateIncrement(Assembler* assembler); |
| 2257 Assembler _assembler_; | 2260 Assembler _assembler_; |
| 2258 GenerateIncrement(&_assembler_); | 2261 GenerateIncrement(&_assembler_); |
| 2259 Code& code = Code::Handle(Code::FinalizeCode( | 2262 Code& code = Code::Handle(Code::FinalizeCode( |
| 2260 *CreateFunction("Test_Code"), &_assembler_)); | 2263 *CreateFunction("Test_Code"), &_assembler_)); |
| 2261 Instructions& instructions = Instructions::Handle(code.instructions()); | 2264 Instructions& instructions = Instructions::Handle(code.instructions()); |
| 2262 typedef int (*IncrementCode)(); | |
| 2263 EXPECT_EQ(2, reinterpret_cast<IncrementCode>(instructions.EntryPoint())()); | |
| 2264 uword entry_point = instructions.EntryPoint(); | 2265 uword entry_point = instructions.EntryPoint(); |
| 2266 intptr_t retval = 0; |
| 2267 #if defined(USING_SIMULATOR) |
| 2268 retval = bit_copy<intptr_t, int64_t>(Simulator::Current()->Call( |
| 2269 static_cast<int32_t>(entry_point), 0, 0, 0, 0)); |
| 2270 #else |
| 2271 typedef intptr_t (*IncrementCode)(); |
| 2272 retval = reinterpret_cast<IncrementCode>(entry_point)(); |
| 2273 #endif |
| 2274 EXPECT_EQ(2, retval); |
| 2265 EXPECT_EQ(instructions.raw(), Instructions::FromEntryPoint(entry_point)); | 2275 EXPECT_EQ(instructions.raw(), Instructions::FromEntryPoint(entry_point)); |
| 2266 } | 2276 } |
| 2267 | 2277 |
| 2268 | 2278 |
| 2269 // Test for Embedded String object in the instructions. | 2279 // Test for Embedded String object in the instructions. |
| 2270 TEST_CASE(EmbedStringInCode) { | 2280 TEST_CASE(EmbedStringInCode) { |
| 2271 extern void GenerateEmbedStringInCode(Assembler* assembler, const char* str); | 2281 extern void GenerateEmbedStringInCode(Assembler* assembler, const char* str); |
| 2272 const char* kHello = "Hello World!"; | 2282 const char* kHello = "Hello World!"; |
| 2273 word expected_length = static_cast<word>(strlen(kHello)); | 2283 word expected_length = static_cast<word>(strlen(kHello)); |
| 2274 Assembler _assembler_; | 2284 Assembler _assembler_; |
| 2275 GenerateEmbedStringInCode(&_assembler_, kHello); | 2285 GenerateEmbedStringInCode(&_assembler_, kHello); |
| 2276 Code& code = Code::Handle(Code::FinalizeCode( | 2286 Code& code = Code::Handle(Code::FinalizeCode( |
| 2277 *CreateFunction("Test_EmbedStringInCode"), &_assembler_)); | 2287 *CreateFunction("Test_EmbedStringInCode"), &_assembler_)); |
| 2278 Instructions& instructions = Instructions::Handle(code.instructions()); | 2288 Instructions& instructions = Instructions::Handle(code.instructions()); |
| 2289 uword retval = 0; |
| 2290 #if defined(USING_SIMULATOR) |
| 2291 retval = bit_copy<uword, int64_t>(Simulator::Current()->Call( |
| 2292 static_cast<int32_t>(instructions.EntryPoint()), 0, 0, 0, 0)); |
| 2293 #else |
| 2279 typedef uword (*EmbedStringCode)(); | 2294 typedef uword (*EmbedStringCode)(); |
| 2280 uword retval = reinterpret_cast<EmbedStringCode>(instructions.EntryPoint())(); | 2295 retval = reinterpret_cast<EmbedStringCode>(instructions.EntryPoint())(); |
| 2296 #endif |
| 2281 EXPECT((retval & kSmiTagMask) == kHeapObjectTag); | 2297 EXPECT((retval & kSmiTagMask) == kHeapObjectTag); |
| 2282 String& string_object = String::Handle(); | 2298 String& string_object = String::Handle(); |
| 2283 string_object ^= reinterpret_cast<RawInstructions*>(retval); | 2299 string_object ^= reinterpret_cast<RawInstructions*>(retval); |
| 2284 EXPECT(string_object.Length() == expected_length); | 2300 EXPECT(string_object.Length() == expected_length); |
| 2285 for (int i = 0; i < expected_length; i ++) { | 2301 for (int i = 0; i < expected_length; i ++) { |
| 2286 EXPECT(string_object.CharAt(i) == kHello[i]); | 2302 EXPECT(string_object.CharAt(i) == kHello[i]); |
| 2287 } | 2303 } |
| 2288 } | 2304 } |
| 2289 | 2305 |
| 2290 | 2306 |
| 2291 // Test for Embedded Smi object in the instructions. | 2307 // Test for Embedded Smi object in the instructions. |
| 2292 TEST_CASE(EmbedSmiInCode) { | 2308 TEST_CASE(EmbedSmiInCode) { |
| 2293 extern void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value); | 2309 extern void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value); |
| 2294 const intptr_t kSmiTestValue = 5; | 2310 const intptr_t kSmiTestValue = 5; |
| 2295 Assembler _assembler_; | 2311 Assembler _assembler_; |
| 2296 GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue); | 2312 GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue); |
| 2297 Code& code = Code::Handle(Code::FinalizeCode( | 2313 Code& code = Code::Handle(Code::FinalizeCode( |
| 2298 *CreateFunction("Test_EmbedSmiInCode"), &_assembler_)); | 2314 *CreateFunction("Test_EmbedSmiInCode"), &_assembler_)); |
| 2299 Instructions& instructions = Instructions::Handle(code.instructions()); | 2315 Instructions& instructions = Instructions::Handle(code.instructions()); |
| 2316 intptr_t retval = 0; |
| 2317 #if defined(USING_SIMULATOR) |
| 2318 retval = bit_copy<intptr_t, int64_t>(Simulator::Current()->Call( |
| 2319 static_cast<int32_t>(instructions.EntryPoint()), 0, 0, 0, 0)); |
| 2320 #else |
| 2300 typedef intptr_t (*EmbedSmiCode)(); | 2321 typedef intptr_t (*EmbedSmiCode)(); |
| 2301 intptr_t retval = | 2322 retval = reinterpret_cast<EmbedSmiCode>(instructions.EntryPoint())(); |
| 2302 reinterpret_cast<EmbedSmiCode>(instructions.EntryPoint())(); | 2323 #endif |
| 2303 EXPECT((retval >> kSmiTagShift) == kSmiTestValue); | 2324 EXPECT((retval >> kSmiTagShift) == kSmiTestValue); |
| 2304 } | 2325 } |
| 2305 | 2326 |
| 2306 | 2327 |
| 2307 #if defined(ARCH_IS_64_BIT) | 2328 #if defined(ARCH_IS_64_BIT) |
| 2308 // Test for Embedded Smi object in the instructions. | 2329 // Test for Embedded Smi object in the instructions. |
| 2309 TEST_CASE(EmbedSmiIn64BitCode) { | 2330 TEST_CASE(EmbedSmiIn64BitCode) { |
| 2310 extern void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value); | 2331 extern void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value); |
| 2311 const intptr_t kSmiTestValue = 5L << 32; | 2332 const intptr_t kSmiTestValue = 5L << 32; |
| 2312 Assembler _assembler_; | 2333 Assembler _assembler_; |
| 2313 GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue); | 2334 GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue); |
| 2314 Code& code = Code::Handle(Code::FinalizeCode( | 2335 Code& code = Code::Handle(Code::FinalizeCode( |
| 2315 *CreateFunction("Test_EmbedSmiIn64BitCode"), &_assembler_)); | 2336 *CreateFunction("Test_EmbedSmiIn64BitCode"), &_assembler_)); |
| 2316 Instructions& instructions = Instructions::Handle(code.instructions()); | 2337 Instructions& instructions = Instructions::Handle(code.instructions()); |
| 2338 intptr_t retval = 0; |
| 2339 #if defined(USING_SIMULATOR) |
| 2340 retval = bit_copy<intptr_t, int64_t>(Simulator::Current()->Call( |
| 2341 static_cast<int32_t>(instructions.EntryPoint()), 0, 0, 0, 0)); |
| 2342 #else |
| 2317 typedef intptr_t (*EmbedSmiCode)(); | 2343 typedef intptr_t (*EmbedSmiCode)(); |
| 2318 intptr_t retval = | 2344 retval = reinterpret_cast<EmbedSmiCode>(instructions.EntryPoint())(); |
| 2319 reinterpret_cast<EmbedSmiCode>(instructions.EntryPoint())(); | 2345 #endif |
| 2320 EXPECT((retval >> kSmiTagShift) == kSmiTestValue); | 2346 EXPECT((retval >> kSmiTagShift) == kSmiTestValue); |
| 2321 } | 2347 } |
| 2322 #endif | 2348 #endif |
| 2323 | 2349 |
| 2324 | 2350 |
| 2325 TEST_CASE(ExceptionHandlers) { | 2351 TEST_CASE(ExceptionHandlers) { |
| 2326 const int kNumEntries = 4; | 2352 const int kNumEntries = 4; |
| 2327 // Add an exception handler table to the code. | 2353 // Add an exception handler table to the code. |
| 2328 ExceptionHandlers& exception_handlers = ExceptionHandlers::Handle(); | 2354 ExceptionHandlers& exception_handlers = ExceptionHandlers::Handle(); |
| 2329 exception_handlers ^= ExceptionHandlers::New(kNumEntries); | 2355 exception_handlers ^= ExceptionHandlers::New(kNumEntries); |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3175 const Function& test6 = Function::Handle(GetFunction(class_a, "test6")); | 3201 const Function& test6 = Function::Handle(GetFunction(class_a, "test6")); |
| 3176 const Function& test7 = Function::Handle(GetFunction(class_a, "test7")); | 3202 const Function& test7 = Function::Handle(GetFunction(class_a, "test7")); |
| 3177 EXPECT_EQ(test1.SourceFingerprint(), test2.SourceFingerprint()); | 3203 EXPECT_EQ(test1.SourceFingerprint(), test2.SourceFingerprint()); |
| 3178 EXPECT_NE(test1.SourceFingerprint(), test3.SourceFingerprint()); | 3204 EXPECT_NE(test1.SourceFingerprint(), test3.SourceFingerprint()); |
| 3179 EXPECT_NE(test3.SourceFingerprint(), test4.SourceFingerprint()); | 3205 EXPECT_NE(test3.SourceFingerprint(), test4.SourceFingerprint()); |
| 3180 EXPECT_NE(test4.SourceFingerprint(), test5.SourceFingerprint()); | 3206 EXPECT_NE(test4.SourceFingerprint(), test5.SourceFingerprint()); |
| 3181 EXPECT_NE(test5.SourceFingerprint(), test6.SourceFingerprint()); | 3207 EXPECT_NE(test5.SourceFingerprint(), test6.SourceFingerprint()); |
| 3182 EXPECT_EQ(test6.SourceFingerprint(), test7.SourceFingerprint()); | 3208 EXPECT_EQ(test6.SourceFingerprint(), test7.SourceFingerprint()); |
| 3183 } | 3209 } |
| 3184 | 3210 |
| 3185 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). | 3211 #endif // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM |
| 3186 | 3212 |
| 3187 } // namespace dart | 3213 } // namespace dart |
| OLD | NEW |