| Index: runtime/vm/code_generator_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/code_generator_ia32.cc (revision 1822)
|
| +++ runtime/vm/code_generator_ia32.cc (working copy)
|
| @@ -33,82 +33,30 @@
|
| #define __ assembler_->
|
|
|
|
|
| -class CodeGeneratorState : public StackResource {
|
| - public:
|
| - explicit CodeGeneratorState(CodeGenerator* codegen)
|
| - : StackResource(Isolate::Current()),
|
| - codegen_(codegen),
|
| - parent_(codegen->state()) {
|
| - if (parent_ != NULL) {
|
| - root_node_ = parent_->root_node_;
|
| - loop_level_ = parent_->loop_level_;
|
| - context_level_ = parent_->context_level_;
|
| - current_try_index_ = parent_->current_try_index_;
|
| - } else {
|
| - root_node_ = NULL;
|
| - loop_level_ = 0;
|
| - context_level_ = 0;
|
| - current_try_index_ = CatchClauseNode::kInvalidTryIndex;
|
| - }
|
| - codegen_->set_state(this);
|
| +CodeGeneratorState::CodeGeneratorState(CodeGenerator* codegen)
|
| + : StackResource(Isolate::Current()),
|
| + codegen_(codegen),
|
| + parent_(codegen->state()) {
|
| + if (parent_ != NULL) {
|
| + root_node_ = parent_->root_node_;
|
| + loop_level_ = parent_->loop_level_;
|
| + context_level_ = parent_->context_level_;
|
| + current_try_index_ = parent_->current_try_index_;
|
| + } else {
|
| + root_node_ = NULL;
|
| + loop_level_ = 0;
|
| + context_level_ = 0;
|
| + current_try_index_ = CatchClauseNode::kInvalidTryIndex;
|
| }
|
| - virtual ~CodeGeneratorState() {
|
| - codegen_->set_state(parent_);
|
| - }
|
| + codegen_->set_state(this);
|
| +}
|
|
|
| - CodeGeneratorState* parent() const { return parent_; }
|
|
|
| - AstNode* root_node() const { return root_node_; }
|
| - void set_root_node(AstNode* value) { root_node_ = value; }
|
| - bool IsRootNode(AstNode* node) const {
|
| - return root_node_ == node;
|
| - }
|
| +CodeGeneratorState::~CodeGeneratorState() {
|
| + codegen_->set_state(parent_);
|
| +}
|
|
|
| - int loop_level() const { return loop_level_; }
|
| - void set_loop_level(int loop_level) {
|
| - loop_level_ = loop_level;
|
| - }
|
|
|
| - int context_level() const { return context_level_; }
|
| - void set_context_level(int context_level) {
|
| - context_level_ = context_level;
|
| - }
|
| -
|
| - int try_index() const { return current_try_index_; }
|
| - void set_try_index(int value) {
|
| - current_try_index_ = value;
|
| - }
|
| -
|
| - private:
|
| - CodeGenerator* codegen_;
|
| - CodeGeneratorState* parent_;
|
| - AstNode* root_node_;
|
| -
|
| - // The loop level reflects the lexical nesting of loop statements, regardless
|
| - // of the presence of captured variables.
|
| - int loop_level_;
|
| -
|
| - // The runtime context level is only incremented when a new context is
|
| - // allocated and chained to the list of contexts. This occurs when the scopes
|
| - // at the current loop level contain captured variables.
|
| - int context_level_;
|
| -
|
| - // We identify each try block in this function with an unique 'try index'
|
| - // value.
|
| - // The 'try index' is used to match the try blocks with the corresponding
|
| - // catch block (if one exists). The PC descriptors generated for
|
| - // statements in the try block use this index so that it can be matched
|
| - // to the appropriate catch block.
|
| - // The 'try index' value is generated by incrementing the try_index_
|
| - // variable in the CodeGenerator object.
|
| - // We store the 'try index' of the block of code that we are
|
| - // currently generating code for in the current_try_index_ variable.
|
| - int current_try_index_;
|
| -
|
| - DISALLOW_IMPLICIT_CONSTRUCTORS(CodeGeneratorState);
|
| -};
|
| -
|
| -
|
| class CodeGenerator::DescriptorList : public ZoneAllocated {
|
| public:
|
| struct PcDesc {
|
| @@ -767,6 +715,45 @@
|
| }
|
|
|
|
|
| +void CodeGenerator::GenerateReturnEpilog() {
|
| + // Unchain the context(s) up to context level 0.
|
| + int context_level = state()->context_level();
|
| + ASSERT(context_level >= 0);
|
| + while (context_level-- > 0) {
|
| + __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
|
| + }
|
| +#ifdef DEBUG
|
| + // Check that the entry stack size matches the exit stack size.
|
| + __ movl(EDX, EBP);
|
| + __ subl(EDX, ESP);
|
| + ASSERT(locals_space_size() >= 0);
|
| + __ cmpl(EDX, Immediate(locals_space_size()));
|
| + Label wrong_stack;
|
| + __ j(NOT_EQUAL, &wrong_stack, Assembler::kNearJump);
|
| +#endif // DEBUG.
|
| +
|
| + if (FLAG_trace_functions) {
|
| + __ pushl(EAX); // Preserve result.
|
| + const Function& function =
|
| + Function::ZoneHandle(parsed_function_.function().raw());
|
| + __ LoadObject(EBX, function);
|
| + __ pushl(EBX);
|
| + GenerateCallRuntime(AstNode::kNoId,
|
| + 0,
|
| + kTraceFunctionExitRuntimeEntry);
|
| + __ popl(EAX); // Remove argument.
|
| + __ popl(EAX); // Restore result.
|
| + }
|
| + __ LeaveFrame();
|
| + __ ret();
|
| +
|
| +#ifdef DEBUG
|
| + __ Bind(&wrong_stack);
|
| + __ Stop("Exit stack size does not match the entry stack size.");
|
| +#endif // DEBUG.
|
| +}
|
| +
|
| +
|
| void CodeGenerator::VisitReturnNode(ReturnNode* node) {
|
| ASSERT(!IsResultNeeded(node));
|
| ASSERT(node->value() != NULL);
|
| @@ -808,41 +795,7 @@
|
| String::ZoneHandle(String::NewSymbol("function result")));
|
| }
|
| }
|
| - // Unchain the context(s) up to context level 0.
|
| - int context_level = state()->context_level();
|
| - ASSERT(context_level >= 0);
|
| - while (context_level-- > 0) {
|
| - __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
|
| - }
|
| -#ifdef DEBUG
|
| - // Check that the entry stack size matches the exit stack size.
|
| - __ movl(EDX, EBP);
|
| - __ subl(EDX, ESP);
|
| - ASSERT(locals_space_size() >= 0);
|
| - __ cmpl(EDX, Immediate(locals_space_size()));
|
| - Label wrong_stack;
|
| - __ j(NOT_EQUAL, &wrong_stack, Assembler::kNearJump);
|
| -#endif // DEBUG.
|
| -
|
| - if (FLAG_trace_functions) {
|
| - __ pushl(EAX); // Preserve result.
|
| - const Function& function =
|
| - Function::ZoneHandle(parsed_function_.function().raw());
|
| - __ LoadObject(EBX, function);
|
| - __ pushl(EBX);
|
| - GenerateCallRuntime(AstNode::kNoId,
|
| - 0,
|
| - kTraceFunctionExitRuntimeEntry);
|
| - __ popl(EAX); // Remove argument.
|
| - __ popl(EAX); // Restore result.
|
| - }
|
| - __ LeaveFrame();
|
| - __ ret();
|
| -
|
| -#ifdef DEBUG
|
| - __ Bind(&wrong_stack);
|
| - __ Stop("Exit stack size does not match the entry stack size.");
|
| -#endif // DEBUG.
|
| + GenerateReturnEpilog();
|
| }
|
|
|
|
|
|
|