Commit 7117ebbd by Ian Lance Taylor

compiler: use temporary variable for stack allocation

    
    Currently, allocation expression that can be allocated on stack
    is implemented with __builtin_alloca, which turns into
    __morestack_allocate_stack_space, which may call C malloc. This
    may be slow. Also if this happens during certain runtime
    functions (e.g. write barrier), bad things might happen (when
    the escape analysis is enabled for the runtime). Make a temporary
    variable on stack for the allocation instead.
    
    Also remove the write barrier in the assignment in building heap
    expression when it is stack allocated.
    
    Reviewed-on: https://go-review.googlesource.com/86242

From-SVN: r256412
parent 4a59d447
bea521d1d8688bea5b14b1ae2a03aec949f48a44 7ef1b48f63c0a64b83fc049884fb89677e19b2dd
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -12387,6 +12387,7 @@ Allocation_expression::do_get_backend(Translate_context* context) ...@@ -12387,6 +12387,7 @@ Allocation_expression::do_get_backend(Translate_context* context)
{ {
Gogo* gogo = context->gogo(); Gogo* gogo = context->gogo();
Location loc = this->location(); Location loc = this->location();
Btype* btype = this->type_->get_backend(gogo);
if (this->allocate_on_stack_) if (this->allocate_on_stack_)
{ {
...@@ -12397,10 +12398,20 @@ Allocation_expression::do_get_backend(Translate_context* context) ...@@ -12397,10 +12398,20 @@ Allocation_expression::do_get_backend(Translate_context* context)
go_assert(saw_errors()); go_assert(saw_errors());
return gogo->backend()->error_expression(); return gogo->backend()->error_expression();
} }
return gogo->backend()->stack_allocation_expression(size, loc); Bstatement* decl;
Named_object* fn = context->function();
go_assert(fn != NULL);
Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
Bexpression* zero = gogo->backend()->zero_expression(btype);
Bvariable* temp =
gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
zero, true, loc, &decl);
Bexpression* ret = gogo->backend()->var_expression(temp, loc);
ret = gogo->backend()->address_expression(ret, loc);
ret = gogo->backend()->compound_expression(decl, ret, loc);
return ret;
} }
Btype* btype = this->type_->get_backend(gogo);
Bexpression* space = Bexpression* space =
gogo->allocate_memory(this->type_, loc)->get_backend(context); gogo->allocate_memory(this->type_, loc)->get_backend(context);
Btype* pbtype = gogo->backend()->pointer_type(btype); Btype* pbtype = gogo->backend()->pointer_type(btype);
...@@ -14278,7 +14289,7 @@ Heap_expression::do_get_backend(Translate_context* context) ...@@ -14278,7 +14289,7 @@ Heap_expression::do_get_backend(Translate_context* context)
// don't do this in the write barrier pass because in some cases // don't do this in the write barrier pass because in some cases
// backend conversion can introduce new Heap_expression values. // backend conversion can introduce new Heap_expression values.
Bstatement* assn; Bstatement* assn;
if (!etype->has_pointer()) if (!etype->has_pointer() || this->allocate_on_stack_)
{ {
space = gogo->backend()->var_expression(space_temp, loc); space = gogo->backend()->var_expression(space_temp, loc);
Bexpression* ref = Bexpression* ref =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment