Cleaned up usage of Function::code, since it may be misunderstood that it points to the only Code object that belongs to that function. That is not the case, there can be several Code object generated for the same function. "Renamed" "code()" to "CurrentCode()", use unoptimized_code where it is clear that we are using unoptimized code only. If compiled, there is a 1:1 correspondence between function and unoptimized code.

Review URL: https://chromiumcodereview.appspot.com//9475031

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@4656 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
srdjan@google.com 2012-02-28 01:31:44 +00:00
parent 9149c6fbfe
commit f6dfa63c9a
15 changed files with 115 additions and 119 deletions

View file

@ -423,7 +423,7 @@ DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) {
Function& target_function = Function::Handle();
CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target);
ASSERT(target_function.HasCode());
uword new_target = Code::Handle(target_function.code()).EntryPoint();
uword new_target = Code::Handle(target_function.CurrentCode()).EntryPoint();
// Verify that we are not patching repeatedly.
ASSERT(target != new_target);
CodePatcher::PatchStaticCallAt(caller_frame->pc(), new_target);
@ -488,7 +488,7 @@ RawCode* ResolveCompileInstanceCallTarget(Isolate* isolate,
functions_cache.AddCompiledFunction(function,
num_arguments,
num_named_arguments);
return function.code();
return function.CurrentCode();
}
}
@ -809,7 +809,7 @@ DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) {
}
}
const Context& context = Context::Handle(closure.context());
const Code& code = Code::Handle(function.code());
const Code& code = Code::Handle(function.CurrentCode());
ASSERT(!code.IsNull());
const Instructions& instrs = Instructions::Handle(code.instructions());
ASSERT(!instrs.IsNull());
@ -976,7 +976,7 @@ DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
function.set_usage_counter(0);
return;
}
if (Code::Handle(function.code()).is_optimized()) {
if (function.HasOptimizedCode()) {
// The caller has been already optimized.
// TODO(srdjan): This is a significant slowdown, the caller is probably in
// a loop. Maybe test if the code has been optimized before calling.
@ -986,15 +986,15 @@ DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
return;
}
if (function.is_optimizable()) {
ASSERT(!Code::Handle(function.code()).is_optimized());
const Code& unoptimized_code = Code::Handle(function.code());
ASSERT(!function.HasOptimizedCode());
const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
// Compilation patches the entry of unoptimized code.
const Error& error =
Error::Handle(Compiler::CompileOptimizedFunction(function));
if (!error.IsNull()) {
Exceptions::PropagateError(error);
}
const Code& optimized_code = Code::Handle(function.code());
const Code& optimized_code = Code::Handle(function.CurrentCode());
ASSERT(!optimized_code.IsNull());
ASSERT(!unoptimized_code.IsNull());
} else {
@ -1022,9 +1022,10 @@ DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) {
uword target = 0;
Function& target_function = Function::Handle();
CodePatcher::GetStaticCallAt(frame->pc(), &target_function, &target);
const uword new_entry_point = Code::Handle(function.code()).EntryPoint();
ASSERT(target != new_entry_point); // Why patch otherwise.
ASSERT(target_function.HasCode());
const uword new_entry_point =
Code::Handle(function.CurrentCode()).EntryPoint();
ASSERT(target != new_entry_point); // Why patch otherwise.
CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point);
if (FLAG_trace_patching) {
OS::Print("FixCallersTarget: patching from 0x%x to '%s' 0x%x\n",
@ -1097,7 +1098,7 @@ DEFINE_RUNTIME_ENTRY(Deoptimize, 1) {
// We have to skip the following otherwise the compiler will complain
// when it attempts to install unoptimized code into a function that
// was already deoptimized.
if (Code::Handle(function.code()).is_optimized()) {
if (function.HasOptimizedCode()) {
// Get unoptimized code. Compilation restores (reenables) the entry of
// unoptimized code.
const Error& error = Error::Handle(Compiler::CompileFunction(function));
@ -1182,7 +1183,7 @@ RawCode* FunctionsCache::LookupCode(const String& function_name,
result ^= cache.At(i + FunctionsCache::kFunction);
ASSERT(!result.IsNull());
ASSERT(result.HasCode());
return result.code();
return result.CurrentCode();
}
}
}

View file

@ -34,8 +34,7 @@ CodeIndexTable::~CodeIndexTable() {
}
void CodeIndexTable::AddFunction(const Function& func) {
const Code& code = Code::Handle(func.code());
void CodeIndexTable::AddCode(const Code& code) {
ASSERT(!code.IsNull());
uword entrypoint = code.EntryPoint(); // Entry point for a function.
intptr_t instr_size = code.Size(); // Instructions size for the function.
@ -48,22 +47,13 @@ void CodeIndexTable::AddFunction(const Function& func) {
}
ASSERT(page_index != -1);
// Add the entrypoint, size and function object at the specified index.
AddFunctionToList(page_index, entrypoint, instr_size, func);
AddCodeToList(page_index, entrypoint, instr_size, code);
} else {
AddLargeFunction(entrypoint, instr_size, func);
AddLargeCode(entrypoint, instr_size, code);
}
}
RawFunction* CodeIndexTable::LookupFunction(uword pc) const {
const Code& code = Code::Handle(LookupCode(pc));
if (code.IsNull()) {
return Function::null();
}
return code.function();
}
RawCode* CodeIndexTable::LookupCode(uword pc) const {
uword page_start = (pc & ~(PageSpace::kPageSize - 1));
int page_index = FindPageIndex(page_start);
@ -131,10 +121,10 @@ int CodeIndexTable::FindPageIndex(uword page_start) const {
}
void CodeIndexTable::AddFunctionToList(int page_index,
uword entrypoint,
intptr_t size,
const Function& func) {
void CodeIndexTable::AddCodeToList(int page_index,
uword entrypoint,
intptr_t size,
const Code& code) {
// Get PC ranges index array at specified index.
IndexArray<PcRange>* pc_ranges = code_pages_->At(page_index).pc_ranges;
ASSERT(pc_ranges != NULL);
@ -146,7 +136,7 @@ void CodeIndexTable::AddFunctionToList(int page_index,
ASSERT(!codes.IsNull());
// Asserting with an unsorted search, to ensure addition of pc was done right.
ASSERT(FindPcIndex(*pc_ranges, entrypoint, kIsNotSorted) == -1);
AddFuncHelper(pc_ranges, codes, entrypoint, size, func);
AddCodeHelper(pc_ranges, codes, entrypoint, size, code);
if (pc_ranges->IsFull()) {
// Grow the pc ranges table and the associated functions table.
int new_size = pc_ranges->length() + kInitialSize;
@ -157,9 +147,9 @@ void CodeIndexTable::AddFunctionToList(int page_index,
}
void CodeIndexTable::AddLargeFunction(uword entrypoint,
intptr_t size,
const Function& func) {
void CodeIndexTable::AddLargeCode(uword entrypoint,
intptr_t size,
const Code& code) {
if (largecode_pc_ranges_ == NULL) {
// No large functions seen so far.
largecode_pc_ranges_ = new IndexArray<PcRange>(kInitialSize);
@ -169,7 +159,7 @@ void CodeIndexTable::AddLargeFunction(uword entrypoint,
ASSERT(FindPcIndex(*largecode_pc_ranges_, entrypoint, kIsNotSorted) == -1);
const Array& largecode_list = Array::Handle(largecode_list_);
ASSERT(!largecode_list.IsNull());
AddFuncHelper(largecode_pc_ranges_, largecode_list, entrypoint, size, func);
AddCodeHelper(largecode_pc_ranges_, largecode_list, entrypoint, size, code);
if (largecode_pc_ranges_->IsFull()) {
// Grow largecode_pc_ranges_ and largecode_list_.
int new_size = largecode_pc_ranges_->length() + kInitialSize;
@ -179,17 +169,17 @@ void CodeIndexTable::AddLargeFunction(uword entrypoint,
}
void CodeIndexTable::AddFuncHelper(IndexArray<PcRange>* pc_ranges,
void CodeIndexTable::AddCodeHelper(IndexArray<PcRange>* pc_ranges,
const Array& codes,
uword entrypoint,
intptr_t size,
const Function& func) {
const Code& code) {
PcRange pc_range;
pc_range.entrypoint = entrypoint;
pc_range.size = size;
intptr_t next_slot = pc_ranges->length();
pc_ranges->Add(pc_range); // pc_range gets added at 'next_slot'.
codes.SetAt(next_slot, Code::Handle(func.code()));
codes.SetAt(next_slot, code);
}

View file

@ -20,27 +20,24 @@ class RawArray;
class RawCode;
class RawFunction;
// This class is used to lookup a Function object given a pc.
// This class is used to lookup a Code object given a pc.
// This functionality is used while stack walking in order to find the Dart
// function corresponding to a frame (enables the pc descriptors for
// a stack frame to be located).
// Most functions fit within a normal page (PageSpace::KPageSize) but some
// functions may have code which is larger than the size of a normal page.
// These functions are referred to as large functions in this code and are
// Most code objects fit within a normal page (PageSpace::KPageSize) but some
// code objects may be larger than the size of a normal page.
// These code objects are referred to as "large codes" in this code and are
// handled by maintaining separate index lists.
class CodeIndexTable {
public:
~CodeIndexTable();
// Add specified compiled function to the code index table.
void AddFunction(const Function& func);
void AddCode(const Code& code);
// Lookup code index table to find the function corresponding to the
// specified 'pc'. If there is no corresponding function a null object
// Lookup code index table to find the code object corresponding to the
// specified 'pc'. If there is no corresponding code object a null object
// is returned.
RawFunction* LookupFunction(uword pc) const;
// Lookup code index table to find corresponding code object.
RawCode* LookupCode(uword pc) const;
// Visit all object pointers (support for GC).
@ -121,23 +118,23 @@ class CodeIndexTable {
// Find the index corresponding to the code page in the index table.
int FindPageIndex(uword page_start) const;
// Add information about a function (entrypoint, size, function object)
// Add information about a code object (entrypoint, size, code object)
// at the specified index of the index table.
void AddFunctionToList(int page_index,
uword entrypoint,
intptr_t size,
const Function& func);
// Add information about a large function (entrypoint, size, function object)
// to the large function list.
void AddLargeFunction(uword entrypoint, intptr_t size, const Function& func);
// Helper function to add a function to the list.
void AddFuncHelper(IndexArray<PcRange>* pc_ranges,
const Array& functions,
void AddCodeToList(int page_index,
uword entrypoint,
intptr_t size,
const Function& func);
const Code& code);
// Add information about a large code object (entrypoint, size, code object)
// to the large code object list.
void AddLargeCode(uword entrypoint, intptr_t size, const Code& code);
// Helper function to add a code object to the list.
void AddCodeHelper(IndexArray<PcRange>* pc_ranges,
const Array& codes,
uword entrypoint,
intptr_t size,
const Code& func);
// Lookup code corresponding to the pc in the large functions list
RawCode* LookupLargeCode(uword pc) const;

View file

@ -123,20 +123,18 @@ TEST_CASE(CodeIndexTable) {
function_name = String::New(buffer);
function = clsA.LookupStaticFunction(function_name);
EXPECT(!function.IsNull());
code = function.code();
code = function.CurrentCode();
EXPECT(code.Size() > 16);
pc = code.EntryPoint() + 16;
EXPECT(code_index_table->LookupFunction(pc) == function.raw());
EXPECT(code_index_table->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.code();
code = function.CurrentCode();
EXPECT(code.Size() > 16);
pc = code.EntryPoint() + 16;
EXPECT(code_index_table->LookupFunction(pc) == function.raw());
EXPECT(code_index_table->LookupCode(pc) == code.raw());
// Lookup the large function
@ -144,15 +142,13 @@ TEST_CASE(CodeIndexTable) {
function_name = String::New(buffer);
function = clsB.LookupStaticFunction(function_name);
EXPECT(!function.IsNull());
code = function.code();
code = function.CurrentCode();
EXPECT(code.Size() > 16);
pc = code.EntryPoint() + 16;
EXPECT(code.Size() > PageSpace::kPageSize);
EXPECT(code_index_table->LookupFunction(pc) == function.raw());
EXPECT(code_index_table->LookupCode(pc) == code.raw());
EXPECT(code.Size() > (1 * MB));
pc = code.EntryPoint() + (1 * MB);
EXPECT(code_index_table->LookupFunction(pc) == function.raw());
EXPECT(code_index_table->LookupCode(pc) == code.raw());
}

View file

@ -161,12 +161,14 @@ static RawError* CompileFunctionHelper(const Function& function,
if (optimized) {
// Transition to optimized code only from unoptimized code ... for now.
ASSERT(function.HasCode());
ASSERT(!Code::Handle(function.code()).is_optimized());
// Do not use type feedback to optimize a function that was deoptimized.
ASSERT(!function.HasOptimizedCode());
// Do not use type feedback to optimize a function that was deoptimized
// too often.
if (parsed_function.function().deoptimization_counter() <
FLAG_deoptimization_counter_threshold) {
ExtractTypeFeedback(Code::Handle(parsed_function.function().code()),
parsed_function.node_sequence());
ExtractTypeFeedback(
Code::Handle(parsed_function.function().unoptimized_code()),
parsed_function.node_sequence());
}
OptimizingCodeGenerator code_gen(&assembler, parsed_function);
code_gen.GenerateCode();
@ -176,7 +178,7 @@ static RawError* CompileFunctionHelper(const Function& function,
code_gen.FinalizePcDescriptors(code);
code_gen.FinalizeExceptionHandlers(code);
function.SetCode(code);
code_index_table->AddFunction(function);
code_index_table->AddCode(code);
CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
if (FLAG_trace_compiler) {
OS::Print("--> patching entry 0x%x\n",
@ -185,7 +187,7 @@ static RawError* CompileFunctionHelper(const Function& function,
} else {
// Unoptimized code.
if (Code::Handle(function.unoptimized_code()).IsNull()) {
ASSERT(Code::Handle(function.code()).IsNull());
ASSERT(!function.HasCode());
// Compiling first time.
CodeGenerator code_gen(&assembler, parsed_function);
code_gen.GenerateCode();
@ -198,15 +200,15 @@ static RawError* CompileFunctionHelper(const Function& function,
function.set_unoptimized_code(code);
function.SetCode(code);
ASSERT(CodePatcher::CodeIsPatchable(code));
code_index_table->AddFunction(function);
code_index_table->AddCode(code);
} else {
// Disable optimized code.
const Code& optimized_code = Code::Handle(function.code());
ASSERT(optimized_code.is_optimized());
CodePatcher::PatchEntry(Code::Handle(function.code()));
ASSERT(function.HasOptimizedCode());
// Patch entry of optimized code
CodePatcher::PatchEntry(Code::Handle(function.CurrentCode()));
if (FLAG_trace_compiler) {
OS::Print("--> patching entry 0x%x\n",
Code::Handle(function.unoptimized_code()).EntryPoint());
Code::Handle(function.CurrentCode()).EntryPoint());
}
// Use previously compiled code.
function.SetCode(Code::Handle(function.unoptimized_code()));
@ -219,12 +221,13 @@ static RawError* CompileFunctionHelper(const Function& function,
}
if (FLAG_trace_compiler) {
OS::Print("--> '%s' entry: 0x%x\n",
function_fullname, Code::Handle(function.code()).EntryPoint());
function_fullname,
Code::Handle(function.CurrentCode()).EntryPoint());
}
if (FLAG_disassemble) {
OS::Print("Code for %sfunction '%s' {\n",
optimized ? "optimized " : "", function_fullname);
const Code& code = Code::Handle(function.code());
const Code& code = Code::Handle(function.CurrentCode());
const Instructions& instructions =
Instructions::Handle(code.instructions());
uword start = instructions.EntryPoint();
@ -360,7 +363,7 @@ RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
func.SetCode(code);
CodeIndexTable* code_index_table = isolate->code_index_table();
ASSERT(code_index_table != NULL);
code_index_table->AddFunction(func);
code_index_table->AddCode(code);
// TODO(hausner): We need a way to remove these one-time execution
// functions from the global code description (PC mapping) tables so
// we don't pollute the system unnecessarily with stale data.

View file

@ -26,10 +26,6 @@ RawObject* DartEntry::InvokeDynamic(
return error.raw();
}
}
const Code& code = Code::Handle(function.code());
ASSERT(!code.IsNull());
const Instructions& instrs = Instructions::Handle(code.instructions());
ASSERT(!instrs.IsNull());
// Set up arguments to include the receiver as the first argument.
const int num_arguments = arguments.length() + 1;
@ -39,15 +35,16 @@ RawObject* DartEntry::InvokeDynamic(
for (int i = 1; i < num_arguments; i++) {
args.Add(arguments[i - 1]);
}
// Now Call the invoke stub which will invoke the dart function.
invokestub entrypoint = reinterpret_cast<invokestub>(
StubCode::InvokeDartCodeEntryPoint());
const Context& context =
Context::ZoneHandle(Isolate::Current()->object_store()->empty_context());
ASSERT(context.isolate() == Isolate::Current());
const Code& code = Code::Handle(function.CurrentCode());
ASSERT(!code.IsNull());
return entrypoint(
instrs.EntryPoint(),
code.EntryPoint(),
CodeGenerator::ArgumentsDescriptor(num_arguments,
optional_arguments_names),
args.data(),
@ -69,19 +66,16 @@ RawObject* DartEntry::InvokeStatic(
return error.raw();
}
}
const Code& code = Code::Handle(function.code());
ASSERT(!code.IsNull());
const Instructions& instrs = Instructions::Handle(code.instructions());
ASSERT(!instrs.IsNull());
// Now Call the invoke stub which will invoke the dart function.
invokestub entrypoint = reinterpret_cast<invokestub>(
StubCode::InvokeDartCodeEntryPoint());
const Context& context =
Context::ZoneHandle(Isolate::Current()->object_store()->empty_context());
ASSERT(context.isolate() == Isolate::Current());
const Code& code = Code::Handle(function.CurrentCode());
ASSERT(!code.IsNull());
return entrypoint(
instrs.EntryPoint(),
code.EntryPoint(),
CodeGenerator::ArgumentsDescriptor(arguments.length(),
optional_arguments_names),
arguments.data(),
@ -106,17 +100,14 @@ RawObject* DartEntry::InvokeClosure(
return error.raw();
}
}
const Code& code = Code::Handle(function.code());
ASSERT(!code.IsNull());
const Instructions& instrs = Instructions::Handle(code.instructions());
ASSERT(!instrs.IsNull());
// Now Call the invoke stub which will invoke the closure.
invokestub entrypoint = reinterpret_cast<invokestub>(
StubCode::InvokeDartCodeEntryPoint());
ASSERT(context.isolate() == Isolate::Current());
const Code& code = Code::Handle(function.CurrentCode());
ASSERT(!code.IsNull());
return entrypoint(
instrs.EntryPoint(),
code.EntryPoint(),
CodeGenerator::ArgumentsDescriptor(arguments.length(),
optional_arguments_names),
arguments.data(),

View file

@ -32,7 +32,8 @@ Breakpoint::Breakpoint(const Function& func, intptr_t pc_desc_index)
line_number_(-1),
is_patched_(false),
next_(NULL) {
Code& code = Code::Handle(func.code());
ASSERT(!func.HasOptimizedCode());
Code& code = Code::Handle(func.unoptimized_code());
ASSERT(!code.IsNull()); // Function must be compiled.
PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
ASSERT(pc_desc_index < desc.Length());
@ -89,7 +90,8 @@ const Function& ActivationFrame::DartFunction() {
ASSERT(Isolate::Current() != NULL);
CodeIndexTable* code_index_table = Isolate::Current()->code_index_table();
ASSERT(code_index_table != NULL);
function_ = code_index_table->LookupFunction(pc_);
const Code& code = Code::Handle(code_index_table->LookupCode(pc_));
function_ = code.function();
}
return function_;
}
@ -138,7 +140,8 @@ RawScript* ActivationFrame::SourceScript() {
intptr_t ActivationFrame::TokenIndex() {
if (token_index_ < 0) {
const Function& func = DartFunction();
Code& code = Code::Handle(func.code());
ASSERT(!func.HasOptimizedCode());
Code& code = Code::Handle(func.unoptimized_code());
ASSERT(!code.IsNull());
PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
for (int i = 0; i < desc.Length(); i++) {
@ -166,7 +169,8 @@ intptr_t ActivationFrame::LineNumber() {
void ActivationFrame::GetDescIndices() {
if (var_descriptors_ == NULL) {
const Code& code = Code::Handle(DartFunction().code());
ASSERT(!DartFunction().HasOptimizedCode());
const Code& code = Code::Handle(DartFunction().unoptimized_code());
var_descriptors_ =
&LocalVarDescriptors::ZoneHandle(code.var_descriptors());
GrowableArray<String*> var_names(8);
@ -420,7 +424,8 @@ void Debugger::InstrumentForStepping(const Function &target_function) {
return;
}
}
Code& code = Code::Handle(target_function.code());
ASSERT(!target_function.HasOptimizedCode());
Code& code = Code::Handle(target_function.unoptimized_code());
ASSERT(!code.IsNull());
PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
for (int i = 0; i < desc.Length(); i++) {
@ -458,7 +463,8 @@ Breakpoint* Debugger::SetBreakpoint(const Function& target_function,
return NULL;
}
}
Code& code = Code::Handle(target_function.code());
ASSERT(!target_function.HasOptimizedCode());
Code& code = Code::Handle(target_function.unoptimized_code());
ASSERT(!code.IsNull());
PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
for (int i = 0; i < desc.Length(); i++) {

View file

@ -429,10 +429,10 @@ void X86Decoder::PrintAddress(uword addr) {
CodeIndexTable* code_index_table = Isolate::Current()->code_index_table();
if (code_index_table != NULL) {
// Print only if jumping to entry point.
const Function& function = Function::Handle(
code_index_table->LookupFunction(addr));
if (!function.IsNull() &&
(Code::Handle(function.code()).EntryPoint() == addr)) {
const Code& code = Code::Handle(
code_index_table->LookupCode(addr));
if (!code.IsNull() && (code.EntryPoint() == addr)) {
const Function& function = Function::Handle(code.function());
const char* name_of_function = function.ToFullyQualifiedCString();
Print(" [");
Print(name_of_function);

View file

@ -83,7 +83,7 @@ DEFINE_NATIVE_ENTRY(TestStaticCallPatching, 0) {
EXPECT(String::Handle(target_function.name()).
Equals(String::Handle(String::New("NativePatchStaticCall"))));
const uword function_entry_address =
Code::Handle(target_function.code()).EntryPoint();
Code::Handle(target_function.CurrentCode()).EntryPoint();
EXPECT_EQ(function_entry_address, target_address);
}

View file

@ -3585,6 +3585,11 @@ bool Function::HasInstantiatedSignature() const {
}
bool Function::HasOptimizedCode() const {
return HasCode() && Code::Handle(raw_ptr()->code_).is_optimized();
}
const char* Function::ToCString() const {
const char* f0 = is_static() ? " static" : "";
const char* f1 = NULL;
@ -7995,9 +8000,10 @@ void Stacktrace::SetupStacktrace(intptr_t index,
const Array& code_array = Array::Handle(raw_ptr()->code_array_);
const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_);
for (intptr_t i = 0; i < frame_pcs.length(); i++) {
function = code_index_table->LookupFunction(frame_pcs[i]);
code = code_index_table->LookupCode(frame_pcs[i]);
ASSERT(!code.IsNull());
function = code.function();
function_array.SetAt((index + i), function);
code = function.code();
code_array.SetAt((index + i), code);
pc_offset = Smi::New(frame_pcs[i] - code.EntryPoint());
pc_offset_array.SetAt((index + i), pc_offset);

View file

@ -1232,9 +1232,13 @@ class Function : public Object {
void SetParameterNameAt(intptr_t index, const String& value) const;
void set_parameter_names(const Array& value) const;
RawCode* code() const { return raw_ptr()->code_; }
// Sets function's code and code's function.
void SetCode(const Code& value) const;
// Return the most recently compiled and installed code for this function.
// It is not the only Code object that points to this function.
RawCode* CurrentCode() const { return raw_ptr()->code_; }
RawCode* unoptimized_code() const { return raw_ptr()->unoptimized_code_; }
void set_unoptimized_code(const Code& value) const;
static intptr_t code_offset() { return OFFSET_OF(RawFunction, code_); }
@ -1358,6 +1362,8 @@ class Function : public Object {
}
void set_is_optimizable(bool value) const;
bool HasOptimizedCode() const;
intptr_t NumberOfParameters() const;
bool AreValidArgumentCounts(int num_arguments, int num_named_arguments) const;
@ -3718,7 +3724,7 @@ void Object::SetRaw(RawObject* value) {
bool Function::HasCode() const {
return code() != Code::null();
return raw_ptr()->code_ != Code::null();
}

View file

@ -2736,7 +2736,7 @@ void OptimizingCodeGenerator::GenerateDirectCall(
intptr_t arg_count,
const Array& optional_argument_names) {
ASSERT(!target.IsNull());
const Code& code = Code::Handle(target.code());
const Code& code = Code::Handle(target.CurrentCode());
ASSERT(!code.IsNull());
ExternalLabel target_label("DirectInstanceCall", code.EntryPoint());

View file

@ -27,7 +27,7 @@ const Function& RegisterFakeFunction(const char* name, const Code& code) {
function.SetCode(code);
CodeIndexTable* code_index_table = Isolate::Current()->code_index_table();
ASSERT(code_index_table != NULL);
code_index_table->AddFunction(function);
code_index_table->AddCode(code);
return function;
}

View file

@ -48,7 +48,7 @@ RawFunction* DartFrame::LookupDartFunction() const {
ASSERT(Isolate::Current() != NULL);
CodeIndexTable* code_index_table = Isolate::Current()->code_index_table();
ASSERT(code_index_table != NULL);
return code_index_table->LookupFunction(pc());
return Code::Handle(code_index_table->LookupCode(pc())).function();
}
@ -97,7 +97,7 @@ bool StubFrame::IsValid() const {
ASSERT(Isolate::Current() != NULL);
CodeIndexTable* code_index_table = Isolate::Current()->code_index_table();
ASSERT(code_index_table != NULL);
return code_index_table->LookupFunction(pc()) == Function::null();
return Code::Handle(code_index_table->LookupCode(pc())).IsNull();
}

View file

@ -175,7 +175,7 @@ void CodeGenTest::Compile() {
function_.SetCode(code);
CodeIndexTable* code_index_table = isolate->code_index_table();
ASSERT(code_index_table != NULL);
code_index_table->AddFunction(function_);
code_index_table->AddCode(code);
retval = true;
} else {
retval = false;