Files
sdk/runtime/vm/code_descriptors.h
T
asiva@google.com 2d3775a1b1 Resubmit change 6302 after fixing the compiler warning on older GCC compiler versions:
Change 6302 description:
- Wire the stack frame iterator to use stack maps for traversing objects if
there are stack maps in the code object. If there are no stack maps it still
does the old style stack frame traversal between fp and sp looking for tagged
pointers.
- Added a mechanism to be able to iterate over the code space and look for a
particular object.
Review URL: https://chromiumcodereview.appspot.com//10030001

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@6331 260f80e4-7a28-3924-810f-c04153c831b5
2012-04-09 18:20:23 +00:00

164 lines
4.5 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.
#ifndef VM_CODE_DESCRIPTORS_H_
#define VM_CODE_DESCRIPTORS_H_
#include "vm/globals.h"
#include "vm/growable_array.h"
#include "vm/object.h"
namespace dart {
class DescriptorList : public ZoneAllocated {
public:
struct PcDesc {
intptr_t pc_offset; // PC offset value of the descriptor.
PcDescriptors::Kind kind; // Descriptor kind (kDeopt, kOther).
intptr_t node_id; // AST node id.
intptr_t token_index; // Token position in source of PC.
intptr_t try_index; // Try block index of PC.
};
DescriptorList() : list_() {
}
~DescriptorList() { }
intptr_t Length() const {
return list_.length();
}
intptr_t PcOffset(int index) const {
return list_[index].pc_offset;
}
PcDescriptors::Kind Kind(int index) const {
return list_[index].kind;
}
intptr_t NodeId(int index) const {
return list_[index].node_id;
}
intptr_t TokenIndex(int index) const {
return list_[index].token_index;
}
intptr_t TryIndex(int index) const {
return list_[index].try_index;
}
void AddDescriptor(PcDescriptors::Kind kind,
intptr_t pc_offset,
intptr_t node_id,
intptr_t token_index,
intptr_t try_index);
RawPcDescriptors* FinalizePcDescriptors(uword entry_point);
private:
GrowableArray<struct PcDesc> list_;
DISALLOW_COPY_AND_ASSIGN(DescriptorList);
};
class StackmapBuilder : public ZoneAllocated {
public:
StackmapBuilder() :
builder_(new BitmapBuilder()),
code_(Code::ZoneHandle()),
stack_map_(Stackmap::ZoneHandle()),
list_(GrowableObjectArray::ZoneHandle(
GrowableObjectArray::New(Heap::kOld))) { }
~StackmapBuilder() { }
// Gets state of stack slot (object or regular value).
bool IsSlotObject(intptr_t stack_slot) const {
ASSERT(builder_ != NULL);
return builder_->Get(stack_slot);
}
// Sets stack slot as containing an object.
void SetSlotAsObject(intptr_t stack_slot) {
ASSERT(builder_ != NULL);
builder_->Set(stack_slot, true);
}
// Sets stack slot as containing regular value.
void SetSlotAsValue(intptr_t stack_slot) {
ASSERT(builder_ != NULL);
builder_->Set(stack_slot, false);
}
// Sets min..max (inclusive) as stack slots containing objects.
void SetSlotRangeAsObject(intptr_t min_stack_slot, intptr_t max_stack_slot) {
ASSERT(builder_ != NULL);
builder_->SetRange(min_stack_slot, max_stack_slot, true);
}
// Sets min..max (inclusive) as stack slots containing regular values.
void SetSlotRangeAsValue(intptr_t min_stack_slot, intptr_t max_stack_slot) {
ASSERT(builder_ != NULL);
builder_->SetRange(min_stack_slot, max_stack_slot, false);
}
void AddEntry(intptr_t pc_offset);
bool Verify();
RawArray* FinalizeStackmaps(const Code& code);
private:
intptr_t Length() const { return list_.Length(); }
RawStackmap* Map(int index) const;
BitmapBuilder* builder_;
Code& code_;
Stackmap& stack_map_;
GrowableObjectArray& list_;
DISALLOW_COPY_AND_ASSIGN(StackmapBuilder);
};
class ExceptionHandlerList : public ZoneAllocated {
public:
struct HandlerDesc {
intptr_t try_index; // Try block index handled by the handler.
intptr_t pc_offset; // Handler PC offset value.
};
ExceptionHandlerList() : list_() {}
intptr_t Length() const {
return list_.length();
}
intptr_t TryIndex(int index) const {
return list_[index].try_index;
}
intptr_t PcOffset(int index) const {
return list_[index].pc_offset;
}
void SetPcOffset(int index, intptr_t handler_pc) {
list_[index].pc_offset = handler_pc;
}
void AddHandler(intptr_t try_index, intptr_t pc_offset) {
struct HandlerDesc data;
data.try_index = try_index;
data.pc_offset = pc_offset;
list_.Add(data);
}
RawExceptionHandlers* FinalizeExceptionHandlers(uword entry_point) {
intptr_t num_handlers = Length();
const ExceptionHandlers& handlers =
ExceptionHandlers::Handle(ExceptionHandlers::New(num_handlers));
for (intptr_t i = 0; i < num_handlers; i++) {
handlers.SetHandlerEntry(i, TryIndex(i), (entry_point + PcOffset(i)));
}
return handlers.raw();
}
private:
GrowableArray<struct HandlerDesc> list_;
DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerList);
};
} // namespace dart
#endif // VM_CODE_DESCRIPTORS_H_