| Index: src/ia32/full-codegen-ia32.cc
|
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
|
| index e067c903091c4e6064d8e9702341792270154985..3c92afa33a669446afd1dec29fb4e12077f08f02 100644
|
| --- a/src/ia32/full-codegen-ia32.cc
|
| +++ b/src/ia32/full-codegen-ia32.cc
|
| @@ -319,10 +319,6 @@ void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
|
|
|
| void FullCodeGenerator::EmitProfilingCounterReset() {
|
| int reset_value = FLAG_interrupt_budget;
|
| - if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) {
|
| - // Self-optimization is a one-off thing: if it fails, don't try again.
|
| - reset_value = Smi::kMaxValue;
|
| - }
|
| __ mov(ebx, Immediate(profiling_counter_));
|
| __ mov(FieldOperand(ebx, Cell::kValueOffset),
|
| Immediate(Smi::FromInt(reset_value)));
|
| @@ -334,13 +330,10 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
|
| Comment cmnt(masm_, "[ Back edge bookkeeping");
|
| Label ok;
|
|
|
| - int weight = 1;
|
| - if (FLAG_weighted_back_edges) {
|
| - ASSERT(back_edge_target->is_bound());
|
| - int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
|
| - weight = Min(kMaxBackEdgeWeight,
|
| - Max(1, distance / kCodeSizeMultiplier));
|
| - }
|
| + ASSERT(back_edge_target->is_bound());
|
| + int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
|
| + int weight = Min(kMaxBackEdgeWeight,
|
| + Max(1, distance / kCodeSizeMultiplier));
|
| EmitProfilingCounterDecrement(weight);
|
| __ j(positive, &ok, Label::kNear);
|
| __ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
|
| @@ -372,31 +365,24 @@ void FullCodeGenerator::EmitReturnSequence() {
|
| __ push(eax);
|
| __ CallRuntime(Runtime::kTraceExit, 1);
|
| }
|
| - if (FLAG_interrupt_at_exit || FLAG_self_optimization) {
|
| - // Pretend that the exit is a backwards jump to the entry.
|
| - int weight = 1;
|
| - if (info_->ShouldSelfOptimize()) {
|
| - weight = FLAG_interrupt_budget / FLAG_self_opt_count;
|
| - } else if (FLAG_weighted_back_edges) {
|
| - int distance = masm_->pc_offset();
|
| - weight = Min(kMaxBackEdgeWeight,
|
| - Max(1, distance / kCodeSizeMultiplier));
|
| - }
|
| - EmitProfilingCounterDecrement(weight);
|
| - Label ok;
|
| - __ j(positive, &ok, Label::kNear);
|
| - __ push(eax);
|
| - if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) {
|
| - __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
| - __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1);
|
| - } else {
|
| - __ call(isolate()->builtins()->InterruptCheck(),
|
| - RelocInfo::CODE_TARGET);
|
| - }
|
| - __ pop(eax);
|
| - EmitProfilingCounterReset();
|
| - __ bind(&ok);
|
| + // Pretend that the exit is a backwards jump to the entry.
|
| + int weight = 1;
|
| + if (info_->ShouldSelfOptimize()) {
|
| + weight = FLAG_interrupt_budget / FLAG_self_opt_count;
|
| + } else {
|
| + int distance = masm_->pc_offset();
|
| + weight = Min(kMaxBackEdgeWeight,
|
| + Max(1, distance / kCodeSizeMultiplier));
|
| }
|
| + EmitProfilingCounterDecrement(weight);
|
| + Label ok;
|
| + __ j(positive, &ok, Label::kNear);
|
| + __ push(eax);
|
| + __ call(isolate()->builtins()->InterruptCheck(),
|
| + RelocInfo::CODE_TARGET);
|
| + __ pop(eax);
|
| + EmitProfilingCounterReset();
|
| + __ bind(&ok);
|
| #ifdef DEBUG
|
| // Add a label for checking the size of the code used for returning.
|
| Label check_exit_codesize;
|
| @@ -1705,6 +1691,10 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
| Comment cmnt(masm_, "[ ArrayLiteral");
|
|
|
| expr->BuildConstantElements(isolate());
|
| + int flags = expr->depth() == 1
|
| + ? ArrayLiteral::kShallowElements
|
| + : ArrayLiteral::kNoFlags;
|
| +
|
| ZoneList<Expression*>* subexprs = expr->values();
|
| int length = subexprs->length();
|
| Handle<FixedArray> constant_elements = expr->constant_elements();
|
| @@ -1716,6 +1706,14 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
| Handle<FixedArrayBase> constant_elements_values(
|
| FixedArrayBase::cast(constant_elements->get(1)));
|
|
|
| + AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites
|
| + ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE;
|
| + if (has_constant_fast_elements && !FLAG_allocation_site_pretenuring) {
|
| + // If the only customer of allocation sites is transitioning, then
|
| + // we can turn it off if we don't have anywhere else to transition to.
|
| + allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
|
| + }
|
| +
|
| Heap* heap = isolate()->heap();
|
| if (has_constant_fast_elements &&
|
| constant_elements_values->map() == heap->fixed_cow_array_map()) {
|
| @@ -1728,7 +1726,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
| __ mov(ecx, Immediate(constant_elements));
|
| FastCloneShallowArrayStub stub(
|
| FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS,
|
| - DONT_TRACK_ALLOCATION_SITE,
|
| + allocation_site_mode,
|
| length);
|
| __ CallStub(&stub);
|
| } else if (expr->depth() > 1 || Serializer::enabled() ||
|
| @@ -1737,20 +1735,18 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
| __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
|
| __ push(Immediate(Smi::FromInt(expr->literal_index())));
|
| __ push(Immediate(constant_elements));
|
| - __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
|
| + __ push(Immediate(Smi::FromInt(flags)));
|
| + __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
|
| } else {
|
| ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
|
| FLAG_smi_only_arrays);
|
| FastCloneShallowArrayStub::Mode mode =
|
| FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
|
| - AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites
|
| - ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE;
|
|
|
| // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot
|
| // change, so it's possible to specialize the stub in advance.
|
| if (has_constant_fast_elements) {
|
| mode = FastCloneShallowArrayStub::CLONE_ELEMENTS;
|
| - allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
|
| }
|
|
|
| __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
| @@ -2235,7 +2231,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|
|
| __ bind(&stub_call);
|
| __ mov(eax, ecx);
|
| - BinaryOpStub stub(op, mode);
|
| + BinaryOpICStub stub(op, mode);
|
| CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET,
|
| expr->BinaryOperationFeedbackId());
|
| patch_site.EmitPatchInfo();
|
| @@ -2320,7 +2316,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
|
| Token::Value op,
|
| OverwriteMode mode) {
|
| __ pop(edx);
|
| - BinaryOpStub stub(op, mode);
|
| + BinaryOpICStub stub(op, mode);
|
| JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
| CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET,
|
| expr->BinaryOperationFeedbackId());
|
| @@ -4404,7 +4400,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
| __ bind(&stub_call);
|
| __ mov(edx, eax);
|
| __ mov(eax, Immediate(Smi::FromInt(1)));
|
| - BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
|
| + BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE);
|
| CallIC(stub.GetCode(isolate()),
|
| RelocInfo::CODE_TARGET,
|
| expr->CountBinOpFeedbackId());
|
| @@ -4837,9 +4833,11 @@ FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
|
|
|
| static const byte kJnsInstruction = 0x79;
|
| static const byte kJnsOffset = 0x11;
|
| -static const byte kCallInstruction = 0xe8;
|
| static const byte kNopByteOne = 0x66;
|
| static const byte kNopByteTwo = 0x90;
|
| +#ifdef DEBUG
|
| +static const byte kCallInstruction = 0xe8;
|
| +#endif
|
|
|
|
|
| void BackEdgeTable::PatchAt(Code* unoptimized_code,
|
|
|