// 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)
  const int kLoopCount = 50000;
#else
  const int kLoopCount = 25000;
#endif
  const int kScriptSize = 512 * KB;
  const int kNumFunctions = 1024;
  char scriptChars[kScriptSize];
  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];

  // Get access to the code index table.
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);

  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));
  String& ambiguity_error_msg = String::Handle();
  clsA = lib.LookupClass(String::Handle(Symbols::New("A")),
                         &ambiguity_error_msg);
  EXPECT(!clsA.IsNull());
  ClassFinalizer::FinalizePendingClasses();
  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));
    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")),
                         &ambiguity_error_msg);
  EXPECT(!clsB.IsNull());
  ClassFinalizer::FinalizePendingClasses();
  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));
    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;
#if defined(TARGET_ARCH_MIPS)
  // MIPS can only Branch +/- 128KB
  EXPECT(code.Size() > (PageSpace::kPageSize / 2));
  EXPECT(Code::LookupCode(pc) == code.raw());
  pc = code.EntryPoint() + (PageSpace::kPageSize / 4);
  EXPECT(Code::LookupCode(pc) == code.raw());
#else
  EXPECT(code.Size() > PageSpace::kPageSize);
  EXPECT(Code::LookupCode(pc) == code.raw());
  EXPECT(code.Size() > (1 * MB));
  pc = code.EntryPoint() + (1 * MB);
  EXPECT(Code::LookupCode(pc) == code.raw());
#endif  // defined(TARGET_ARCH_MIPS)
}

}  // namespace dart
