Files
sdk/runtime/vm/find_code_object_test.cc
T
zra@google.com 7c28e8d96d Fixes FindCodeObject test.
After enabling GC of unoptimized code, functions cannot be
used as proxies for unoptimized code. This change, creates
ZoneHanldes for compiled code in the FindCodeObject test,
so that later when functions are used to refer to code,
we can be sure that the code will be there.

TBR: iposva

Review URL: https://codereview.chromium.org//82713009

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@30604 260f80e4-7a28-3924-810f-c04153c831b5
2013-11-23 19:09:23 +00:00

159 lines
5.7 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "platform/assert.h"
#include "vm/class_finalizer.h"
#include "vm/compiler.h"
#include "vm/object.h"
#include "vm/pages.h"
#include "vm/stack_frame.h"
#include "vm/symbols.h"
#include "vm/unit_test.h"
namespace dart {
TEST_CASE(FindCodeObject) {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
const int kLoopCount = 50000;
#else
const int kLoopCount = 25000;
#endif
const int kScriptSize = 512 * KB;
const int kNumFunctions = 1024;
char scriptChars[kScriptSize];
// Get access to the code index table.
Isolate* isolate = Isolate::Current();
ASSERT(isolate != NULL);
StackZone zone(isolate);
String& url = String::Handle(String::New("dart-test:FindCodeObject"));
String& source = String::Handle();
Script& script = Script::Handle();
Library& lib = Library::Handle();
Class& clsA = Class::Handle();
Class& clsB = Class::Handle();
String& function_name = String::Handle();
Function& function = Function::Handle();
char buffer[256];
lib = Library::CoreLibrary();
// Load up class A with 1024 functions.
int written = OS::SNPrint(scriptChars, kScriptSize, "class A {");
for (int i = 0; i < kNumFunctions; i++) {
OS::SNPrint(buffer,
256,
"static foo%d([int i=1,int j=2,int k=3]){return i+j+k;}", i);
written += OS::SNPrint((scriptChars + written),
(kScriptSize - written),
"%s",
buffer);
}
OS::SNPrint((scriptChars + written), (kScriptSize - written), "}");
source = String::New(scriptChars);
script = Script::New(url, source, RawScript::kScriptTag);
EXPECT(CompilerTest::TestCompileScript(lib, script));
clsA = lib.LookupClass(String::Handle(Symbols::New("A")));
EXPECT(!clsA.IsNull());
ClassFinalizer::FinalizeTypeHierarchy();
for (int i = 0; i < kNumFunctions; i++) {
OS::SNPrint(buffer, 256, "foo%d", i);
function_name = String::New(buffer);
function = clsA.LookupStaticFunction(function_name);
EXPECT(!function.IsNull());
EXPECT(CompilerTest::TestCompileFunction(function));
const Code& code = Code::ZoneHandle(function.CurrentCode());
EXPECT(!code.IsNull())
EXPECT(function.HasCode());
}
// Now load up class B with 1024 functions.
written = OS::SNPrint(scriptChars, kScriptSize, "class B {");
// Create one large function.
OS::SNPrint(buffer, sizeof(buffer), "static moo0([var i=1]) { ");
written += OS::SNPrint((scriptChars + written),
(kScriptSize - written),
"%s",
buffer);
// Generate a large function so that the code for this function when
// compiled will reside in a large page.
for (int i = 0; i < kLoopCount; i++) {
OS::SNPrint(buffer, sizeof(buffer), "i = i+i;");
written += OS::SNPrint((scriptChars + written),
(kScriptSize - written),
"%s",
buffer);
}
OS::SNPrint(buffer, sizeof(buffer), "return i; }");
written += OS::SNPrint((scriptChars + written),
(kScriptSize - written),
"%s",
buffer);
for (int i = 1; i < kNumFunctions; i++) {
OS::SNPrint(buffer,
256,
"static moo%d([int i=1,int j=2,int k=3]){return i+j+k;}", i);
written += OS::SNPrint((scriptChars + written),
(kScriptSize - written),
"%s",
buffer);
}
OS::SNPrint((scriptChars + written), (kScriptSize - written), "}");
url = String::New("dart-test:FindCodeObject");
source = String::New(scriptChars);
script = Script::New(url, source, RawScript::kScriptTag);
EXPECT(CompilerTest::TestCompileScript(lib, script));
clsB = lib.LookupClass(String::Handle(Symbols::New("B")));
EXPECT(!clsB.IsNull());
ClassFinalizer::FinalizeTypeHierarchy();
for (int i = 0; i < kNumFunctions; i++) {
OS::SNPrint(buffer, 256, "moo%d", i);
function_name = String::New(buffer);
function = clsB.LookupStaticFunction(function_name);
EXPECT(!function.IsNull());
EXPECT(CompilerTest::TestCompileFunction(function));
const Code& code = Code::ZoneHandle(function.CurrentCode());
EXPECT(!code.IsNull());
EXPECT(function.HasCode());
}
// Now try and access these functions using the code index table.
Code& code = Code::Handle();
uword pc;
OS::SNPrint(buffer, 256, "foo%d", 123);
function_name = String::New(buffer);
function = clsA.LookupStaticFunction(function_name);
EXPECT(!function.IsNull());
code = function.CurrentCode();
EXPECT(code.Size() > 16);
pc = code.EntryPoint() + 16;
EXPECT(Code::LookupCode(pc) == code.raw());
OS::SNPrint(buffer, 256, "moo%d", 54);
function_name = String::New(buffer);
function = clsB.LookupStaticFunction(function_name);
EXPECT(!function.IsNull());
code = function.CurrentCode();
EXPECT(code.Size() > 16);
pc = code.EntryPoint() + 16;
EXPECT(Code::LookupCode(pc) == code.raw());
// Lookup the large function
OS::SNPrint(buffer, 256, "moo%d", 0);
function_name = String::New(buffer);
function = clsB.LookupStaticFunction(function_name);
EXPECT(!function.IsNull());
code = function.CurrentCode();
EXPECT(code.Size() > 16);
pc = code.EntryPoint() + 16;
EXPECT(code.Size() > (PageSpace::kPageSizeInWords << kWordSizeLog2));
EXPECT(Code::LookupCode(pc) == code.raw());
EXPECT(code.Size() > (1 * MB));
pc = code.EntryPoint() + (1 * MB);
EXPECT(Code::LookupCode(pc) == code.raw());
}
} // namespace dart