| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #include "platform/assert.h" | |
| 6 #include "vm/class_finalizer.h" | |
| 7 #include "vm/compiler.h" | |
| 8 #include "vm/object.h" | |
| 9 #include "vm/pages.h" | |
| 10 #include "vm/stack_frame.h" | |
| 11 #include "vm/unit_test.h" | |
| 12 | |
| 13 namespace dart { | |
| 14 | |
| 15 // Compiler only implemented on IA32 and x64 now. | |
| 16 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) | |
| 17 | |
| 18 TEST_CASE(CodeIndexTable) { | |
| 19 #if defined(TARGET_ARCH_IA32) | |
| 20 const int kLoopCount = 50000; | |
| 21 #else | |
| 22 const int kLoopCount = 25000; | |
| 23 #endif | |
| 24 const int kScriptSize = 512 * KB; | |
| 25 const int kNumFunctions = 1024; | |
| 26 char scriptChars[kScriptSize]; | |
| 27 String& url = String::Handle(String::New("dart-test:CodeIndexTable")); | |
| 28 String& source = String::Handle(); | |
| 29 Script& script = Script::Handle(); | |
| 30 Library& lib = Library::Handle(); | |
| 31 Class& clsA = Class::Handle(); | |
| 32 Class& clsB = Class::Handle(); | |
| 33 String& function_name = String::Handle(); | |
| 34 Function& function = Function::Handle(); | |
| 35 char buffer[256]; | |
| 36 | |
| 37 // Get access to the code index table. | |
| 38 Isolate* isolate = Isolate::Current(); | |
| 39 ASSERT(isolate != NULL); | |
| 40 | |
| 41 lib = Library::CoreLibrary(); | |
| 42 | |
| 43 // Load up class A with 1024 functions. | |
| 44 int written = OS::SNPrint(scriptChars, kScriptSize, "class A {"); | |
| 45 for (int i = 0; i < kNumFunctions; i++) { | |
| 46 OS::SNPrint(buffer, | |
| 47 256, | |
| 48 "static foo%d([int i=1,int j=2,int k=3]){return i+j+k;}", i); | |
| 49 written += OS::SNPrint((scriptChars + written), | |
| 50 (kScriptSize - written), | |
| 51 "%s", | |
| 52 buffer); | |
| 53 } | |
| 54 OS::SNPrint((scriptChars + written), (kScriptSize - written), "}"); | |
| 55 source = String::New(scriptChars); | |
| 56 script = Script::New(url, source, RawScript::kSource); | |
| 57 EXPECT(CompilerTest::TestCompileScript(lib, script)); | |
| 58 clsA = lib.LookupClass(String::Handle(String::NewSymbol("A"))); | |
| 59 EXPECT(!clsA.IsNull()); | |
| 60 ClassFinalizer::FinalizePendingClasses(); | |
| 61 for (int i = 0; i < kNumFunctions; i++) { | |
| 62 OS::SNPrint(buffer, 256, "foo%d", i); | |
| 63 function_name = String::New(buffer); | |
| 64 function = clsA.LookupStaticFunction(function_name); | |
| 65 EXPECT(!function.IsNull()); | |
| 66 EXPECT(CompilerTest::TestCompileFunction(function)); | |
| 67 EXPECT(function.HasCode()); | |
| 68 } | |
| 69 | |
| 70 // Now load up class B with 1024 functions. | |
| 71 written = OS::SNPrint(scriptChars, kScriptSize, "class B {"); | |
| 72 // Create one large function. | |
| 73 OS::SNPrint(buffer, sizeof(buffer), "static moo0([var i=1]) { "); | |
| 74 written += OS::SNPrint((scriptChars + written), | |
| 75 (kScriptSize - written), | |
| 76 "%s", | |
| 77 buffer); | |
| 78 // Generate a large function so that the code for this function when | |
| 79 // compiled will reside in a large page. | |
| 80 for (int i = 0; i < kLoopCount; i++) { | |
| 81 OS::SNPrint(buffer, sizeof(buffer), "i = i+i;"); | |
| 82 written += OS::SNPrint((scriptChars + written), | |
| 83 (kScriptSize - written), | |
| 84 "%s", | |
| 85 buffer); | |
| 86 } | |
| 87 OS::SNPrint(buffer, sizeof(buffer), "return i; }"); | |
| 88 written += OS::SNPrint((scriptChars + written), | |
| 89 (kScriptSize - written), | |
| 90 "%s", | |
| 91 buffer); | |
| 92 for (int i = 1; i < kNumFunctions; i++) { | |
| 93 OS::SNPrint(buffer, | |
| 94 256, | |
| 95 "static moo%d([int i=1,int j=2,int k=3]){return i+j+k;}", i); | |
| 96 written += OS::SNPrint((scriptChars + written), | |
| 97 (kScriptSize - written), | |
| 98 "%s", | |
| 99 buffer); | |
| 100 } | |
| 101 OS::SNPrint((scriptChars + written), (kScriptSize - written), "}"); | |
| 102 url = String::New("dart-test:CodeIndexTable"); | |
| 103 source = String::New(scriptChars); | |
| 104 script = Script::New(url, source, RawScript::kSource); | |
| 105 EXPECT(CompilerTest::TestCompileScript(lib, script)); | |
| 106 clsB = lib.LookupClass(String::Handle(String::NewSymbol("B"))); | |
| 107 EXPECT(!clsB.IsNull()); | |
| 108 ClassFinalizer::FinalizePendingClasses(); | |
| 109 for (int i = 0; i < kNumFunctions; i++) { | |
| 110 OS::SNPrint(buffer, 256, "moo%d", i); | |
| 111 function_name = String::New(buffer); | |
| 112 function = clsB.LookupStaticFunction(function_name); | |
| 113 EXPECT(!function.IsNull()); | |
| 114 EXPECT(CompilerTest::TestCompileFunction(function)); | |
| 115 EXPECT(function.HasCode()); | |
| 116 } | |
| 117 | |
| 118 // Now try and access these functions using the code index table. | |
| 119 Code& code = Code::Handle(); | |
| 120 uword pc; | |
| 121 OS::SNPrint(buffer, 256, "foo%d", 123); | |
| 122 function_name = String::New(buffer); | |
| 123 function = clsA.LookupStaticFunction(function_name); | |
| 124 EXPECT(!function.IsNull()); | |
| 125 code = function.CurrentCode(); | |
| 126 EXPECT(code.Size() > 16); | |
| 127 pc = code.EntryPoint() + 16; | |
| 128 EXPECT(StackFrame::LookupCode(isolate, pc) == code.raw()); | |
| 129 | |
| 130 OS::SNPrint(buffer, 256, "moo%d", 54); | |
| 131 function_name = String::New(buffer); | |
| 132 function = clsB.LookupStaticFunction(function_name); | |
| 133 EXPECT(!function.IsNull()); | |
| 134 code = function.CurrentCode(); | |
| 135 EXPECT(code.Size() > 16); | |
| 136 pc = code.EntryPoint() + 16; | |
| 137 EXPECT(StackFrame::LookupCode(isolate, pc) == code.raw()); | |
| 138 | |
| 139 // Lookup the large function | |
| 140 OS::SNPrint(buffer, 256, "moo%d", 0); | |
| 141 function_name = String::New(buffer); | |
| 142 function = clsB.LookupStaticFunction(function_name); | |
| 143 EXPECT(!function.IsNull()); | |
| 144 code = function.CurrentCode(); | |
| 145 EXPECT(code.Size() > 16); | |
| 146 pc = code.EntryPoint() + 16; | |
| 147 EXPECT(code.Size() > PageSpace::kPageSize); | |
| 148 EXPECT(StackFrame::LookupCode(isolate, pc) == code.raw()); | |
| 149 EXPECT(code.Size() > (1 * MB)); | |
| 150 pc = code.EntryPoint() + (1 * MB); | |
| 151 EXPECT(StackFrame::LookupCode(isolate, pc) == code.raw()); | |
| 152 } | |
| 153 | |
| 154 #endif // TARGET_ARCH_IA32 || TARGET_ARCH_X64 | |
| 155 | |
| 156 } // namespace dart | |
| OLD | NEW |