Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: src/mips/full-codegen-mips.cc

Issue 141363005: A64: Synchronize with r15204. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 // o fp: our caller's frame pointer 131 // o fp: our caller's frame pointer
132 // o sp: stack pointer 132 // o sp: stack pointer
133 // o ra: return address 133 // o ra: return address
134 // 134 //
135 // The function builds a JS frame. Please see JavaScriptFrameConstants in 135 // The function builds a JS frame. Please see JavaScriptFrameConstants in
136 // frames-mips.h for its layout. 136 // frames-mips.h for its layout.
137 void FullCodeGenerator::Generate() { 137 void FullCodeGenerator::Generate() {
138 CompilationInfo* info = info_; 138 CompilationInfo* info = info_;
139 handler_table_ = 139 handler_table_ =
140 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 140 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
141 profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell( 141 profiling_counter_ = isolate()->factory()->NewCell(
142 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 142 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
143 SetFunctionPosition(function()); 143 SetFunctionPosition(function());
144 Comment cmnt(masm_, "[ function compiled by full code generator"); 144 Comment cmnt(masm_, "[ function compiled by full code generator");
145 145
146 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 146 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
147 147
148 #ifdef DEBUG 148 #ifdef DEBUG
149 if (strlen(FLAG_stop_at) > 0 && 149 if (strlen(FLAG_stop_at) > 0 &&
150 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 150 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
151 __ stop("stop-at"); 151 __ stop("stop-at");
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 319
320 320
321 void FullCodeGenerator::ClearAccumulator() { 321 void FullCodeGenerator::ClearAccumulator() {
322 ASSERT(Smi::FromInt(0) == 0); 322 ASSERT(Smi::FromInt(0) == 0);
323 __ mov(v0, zero_reg); 323 __ mov(v0, zero_reg);
324 } 324 }
325 325
326 326
327 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { 327 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
328 __ li(a2, Operand(profiling_counter_)); 328 __ li(a2, Operand(profiling_counter_));
329 __ lw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset)); 329 __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset));
330 __ Subu(a3, a3, Operand(Smi::FromInt(delta))); 330 __ Subu(a3, a3, Operand(Smi::FromInt(delta)));
331 __ sw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset)); 331 __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset));
332 } 332 }
333 333
334 334
335 void FullCodeGenerator::EmitProfilingCounterReset() { 335 void FullCodeGenerator::EmitProfilingCounterReset() {
336 int reset_value = FLAG_interrupt_budget; 336 int reset_value = FLAG_interrupt_budget;
337 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) { 337 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) {
338 // Self-optimization is a one-off thing: if it fails, don't try again. 338 // Self-optimization is a one-off thing: if it fails, don't try again.
339 reset_value = Smi::kMaxValue; 339 reset_value = Smi::kMaxValue;
340 } 340 }
341 if (isolate()->IsDebuggerActive()) { 341 if (isolate()->IsDebuggerActive()) {
342 // Detect debug break requests as soon as possible. 342 // Detect debug break requests as soon as possible.
343 reset_value = FLAG_interrupt_budget >> 4; 343 reset_value = FLAG_interrupt_budget >> 4;
344 } 344 }
345 __ li(a2, Operand(profiling_counter_)); 345 __ li(a2, Operand(profiling_counter_));
346 __ li(a3, Operand(Smi::FromInt(reset_value))); 346 __ li(a3, Operand(Smi::FromInt(reset_value)));
347 __ sw(a3, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset)); 347 __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset));
348 } 348 }
349 349
350 350
351 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, 351 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
352 Label* back_edge_target) { 352 Label* back_edge_target) {
353 // The generated code is used in Deoptimizer::PatchStackCheckCodeAt so we need 353 // The generated code is used in Deoptimizer::PatchStackCheckCodeAt so we need
354 // to make sure it is constant. Branch may emit a skip-or-jump sequence 354 // to make sure it is constant. Branch may emit a skip-or-jump sequence
355 // instead of the normal Branch. It seems that the "skip" part of that 355 // instead of the normal Branch. It seems that the "skip" part of that
356 // sequence is about as long as this Branch would be so it is safe to ignore 356 // sequence is about as long as this Branch would be so it is safe to ignore
357 // that. 357 // that.
358 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 358 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
359 Comment cmnt(masm_, "[ Back edge bookkeeping"); 359 Comment cmnt(masm_, "[ Back edge bookkeeping");
360 Label ok; 360 Label ok;
361 int weight = 1; 361 int weight = 1;
362 if (FLAG_weighted_back_edges) { 362 if (FLAG_weighted_back_edges) {
363 ASSERT(back_edge_target->is_bound()); 363 ASSERT(back_edge_target->is_bound());
364 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); 364 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
365 weight = Min(kMaxBackEdgeWeight, 365 weight = Min(kMaxBackEdgeWeight,
366 Max(1, distance / kBackEdgeDistanceUnit)); 366 Max(1, distance / kCodeSizeMultiplier));
367 } 367 }
368 EmitProfilingCounterDecrement(weight); 368 EmitProfilingCounterDecrement(weight);
369 __ slt(at, a3, zero_reg); 369 __ slt(at, a3, zero_reg);
370 __ beq(at, zero_reg, &ok); 370 __ beq(at, zero_reg, &ok);
371 // CallStub will emit a li t9 first, so it is safe to use the delay slot. 371 // CallStub will emit a li t9 first, so it is safe to use the delay slot.
372 InterruptStub stub; 372 InterruptStub stub;
373 __ CallStub(&stub); 373 __ CallStub(&stub);
374 // Record a mapping of this PC offset to the OSR id. This is used to find 374 // Record a mapping of this PC offset to the OSR id. This is used to find
375 // the AST id from the unoptimized code in order to use it as a key into 375 // the AST id from the unoptimized code in order to use it as a key into
376 // the deoptimization input data found in the optimized code. 376 // the deoptimization input data found in the optimized code.
(...skipping 22 matching lines...) Expand all
399 __ CallRuntime(Runtime::kTraceExit, 1); 399 __ CallRuntime(Runtime::kTraceExit, 1);
400 } 400 }
401 if (FLAG_interrupt_at_exit || FLAG_self_optimization) { 401 if (FLAG_interrupt_at_exit || FLAG_self_optimization) {
402 // Pretend that the exit is a backwards jump to the entry. 402 // Pretend that the exit is a backwards jump to the entry.
403 int weight = 1; 403 int weight = 1;
404 if (info_->ShouldSelfOptimize()) { 404 if (info_->ShouldSelfOptimize()) {
405 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 405 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
406 } else if (FLAG_weighted_back_edges) { 406 } else if (FLAG_weighted_back_edges) {
407 int distance = masm_->pc_offset(); 407 int distance = masm_->pc_offset();
408 weight = Min(kMaxBackEdgeWeight, 408 weight = Min(kMaxBackEdgeWeight,
409 Max(1, distance / kBackEdgeDistanceUnit)); 409 Max(1, distance / kCodeSizeMultiplier));
410 } 410 }
411 EmitProfilingCounterDecrement(weight); 411 EmitProfilingCounterDecrement(weight);
412 Label ok; 412 Label ok;
413 __ Branch(&ok, ge, a3, Operand(zero_reg)); 413 __ Branch(&ok, ge, a3, Operand(zero_reg));
414 __ push(v0); 414 __ push(v0);
415 if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) { 415 if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) {
416 __ lw(a2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 416 __ lw(a2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
417 __ push(a2); 417 __ push(a2);
418 __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1); 418 __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1);
419 } else { 419 } else {
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 __ jmp(&loop); 1157 __ jmp(&loop);
1158 1158
1159 __ bind(&no_descriptors); 1159 __ bind(&no_descriptors);
1160 __ Drop(1); 1160 __ Drop(1);
1161 __ jmp(&exit); 1161 __ jmp(&exit);
1162 1162
1163 // We got a fixed array in register v0. Iterate through that. 1163 // We got a fixed array in register v0. Iterate through that.
1164 Label non_proxy; 1164 Label non_proxy;
1165 __ bind(&fixed_array); 1165 __ bind(&fixed_array);
1166 1166
1167 Handle<JSGlobalPropertyCell> cell = 1167 Handle<Cell> cell = isolate()->factory()->NewCell(
1168 isolate()->factory()->NewJSGlobalPropertyCell( 1168 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
1169 Handle<Object>( 1169 isolate()));
1170 Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
1171 isolate()));
1172 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); 1170 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
1173 __ LoadHeapObject(a1, cell); 1171 __ LoadHeapObject(a1, cell);
1174 __ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); 1172 __ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
1175 __ sw(a2, FieldMemOperand(a1, JSGlobalPropertyCell::kValueOffset)); 1173 __ sw(a2, FieldMemOperand(a1, Cell::kValueOffset));
1176 1174
1177 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check 1175 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
1178 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object 1176 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
1179 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1177 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1180 __ GetObjectType(a2, a3, a3); 1178 __ GetObjectType(a2, a3, a3);
1181 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE)); 1179 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE));
1182 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy 1180 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy
1183 __ bind(&non_proxy); 1181 __ bind(&non_proxy);
1184 __ Push(a1, v0); // Smi and array 1182 __ Push(a1, v0); // Smi and array
1185 __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); 1183 __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset));
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 for (int i = 0; i < length; i++) { 1833 for (int i = 0; i < length; i++) {
1836 Expression* subexpr = subexprs->at(i); 1834 Expression* subexpr = subexprs->at(i);
1837 // If the subexpression is a literal or a simple materialized literal it 1835 // If the subexpression is a literal or a simple materialized literal it
1838 // is already set in the cloned array. 1836 // is already set in the cloned array.
1839 if (subexpr->AsLiteral() != NULL || 1837 if (subexpr->AsLiteral() != NULL ||
1840 CompileTimeValue::IsCompileTimeValue(subexpr)) { 1838 CompileTimeValue::IsCompileTimeValue(subexpr)) {
1841 continue; 1839 continue;
1842 } 1840 }
1843 1841
1844 if (!result_saved) { 1842 if (!result_saved) {
1845 __ push(v0); 1843 __ push(v0); // array literal
1844 __ Push(Smi::FromInt(expr->literal_index()));
1846 result_saved = true; 1845 result_saved = true;
1847 } 1846 }
1848 1847
1849 VisitForAccumulatorValue(subexpr); 1848 VisitForAccumulatorValue(subexpr);
1850 1849
1851 if (IsFastObjectElementsKind(constant_elements_kind)) { 1850 if (IsFastObjectElementsKind(constant_elements_kind)) {
1852 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1851 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1853 __ lw(t2, MemOperand(sp)); // Copy of array literal. 1852 __ lw(t2, MemOperand(sp, kPointerSize)); // Copy of array literal.
1854 __ lw(a1, FieldMemOperand(t2, JSObject::kElementsOffset)); 1853 __ lw(a1, FieldMemOperand(t2, JSObject::kElementsOffset));
1855 __ sw(result_register(), FieldMemOperand(a1, offset)); 1854 __ sw(result_register(), FieldMemOperand(a1, offset));
1856 // Update the write barrier for the array store. 1855 // Update the write barrier for the array store.
1857 __ RecordWriteField(a1, offset, result_register(), a2, 1856 __ RecordWriteField(a1, offset, result_register(), a2,
1858 kRAHasBeenSaved, kDontSaveFPRegs, 1857 kRAHasBeenSaved, kDontSaveFPRegs,
1859 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); 1858 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
1860 } else { 1859 } else {
1861 __ lw(a1, MemOperand(sp)); // Copy of array literal.
1862 __ lw(a2, FieldMemOperand(a1, JSObject::kMapOffset));
1863 __ li(a3, Operand(Smi::FromInt(i))); 1860 __ li(a3, Operand(Smi::FromInt(i)));
1864 __ li(t0, Operand(Smi::FromInt(expr->literal_index())));
1865 __ mov(a0, result_register()); 1861 __ mov(a0, result_register());
1866 StoreArrayLiteralElementStub stub; 1862 StoreArrayLiteralElementStub stub;
1867 __ CallStub(&stub); 1863 __ CallStub(&stub);
1868 } 1864 }
1869 1865
1870 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1866 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1871 } 1867 }
1872 if (result_saved) { 1868 if (result_saved) {
1869 __ Pop(); // literal index
1873 context()->PlugTOS(); 1870 context()->PlugTOS();
1874 } else { 1871 } else {
1875 context()->Plug(v0); 1872 context()->Plug(v0);
1876 } 1873 }
1877 } 1874 }
1878 1875
1879 1876
1880 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1877 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1881 Comment cmnt(masm_, "[ Assignment"); 1878 Comment cmnt(masm_, "[ Assignment");
1882 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 1879 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1991 } 1988 }
1992 1989
1993 1990
1994 void FullCodeGenerator::VisitYield(Yield* expr) { 1991 void FullCodeGenerator::VisitYield(Yield* expr) {
1995 Comment cmnt(masm_, "[ Yield"); 1992 Comment cmnt(masm_, "[ Yield");
1996 // Evaluate yielded value first; the initial iterator definition depends on 1993 // Evaluate yielded value first; the initial iterator definition depends on
1997 // this. It stays on the stack while we update the iterator. 1994 // this. It stays on the stack while we update the iterator.
1998 VisitForStackValue(expr->expression()); 1995 VisitForStackValue(expr->expression());
1999 1996
2000 switch (expr->yield_kind()) { 1997 switch (expr->yield_kind()) {
2001 case Yield::INITIAL: 1998 case Yield::SUSPEND:
2002 case Yield::SUSPEND: { 1999 // Pop value from top-of-stack slot; box result into result register.
2000 EmitCreateIteratorResult(false);
2001 __ push(result_register());
2002 // Fall through.
2003 case Yield::INITIAL: {
2003 VisitForStackValue(expr->generator_object()); 2004 VisitForStackValue(expr->generator_object());
2004 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2005 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2005 __ lw(context_register(), 2006 __ lw(context_register(),
2006 MemOperand(fp, StandardFrameConstants::kContextOffset)); 2007 MemOperand(fp, StandardFrameConstants::kContextOffset));
2007 2008
2008 Label resume; 2009 Label resume;
2009 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2010 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2010 __ Branch(&resume, ne, result_register(), Operand(at)); 2011 __ Branch(&resume, ne, result_register(), Operand(at));
2011 if (expr->yield_kind() == Yield::SUSPEND) { 2012 __ pop(result_register());
2012 EmitReturnIteratorResult(false); 2013 EmitReturnSequence();
2013 } else {
2014 __ pop(result_register());
2015 EmitReturnSequence();
2016 }
2017 2014
2018 __ bind(&resume); 2015 __ bind(&resume);
2019 context()->Plug(result_register()); 2016 context()->Plug(result_register());
2020 break; 2017 break;
2021 } 2018 }
2022 2019
2023 case Yield::FINAL: { 2020 case Yield::FINAL: {
2024 VisitForAccumulatorValue(expr->generator_object()); 2021 VisitForAccumulatorValue(expr->generator_object());
2025 __ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); 2022 __ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
2026 __ sw(a1, FieldMemOperand(result_register(), 2023 __ sw(a1, FieldMemOperand(result_register(),
2027 JSGeneratorObject::kContinuationOffset)); 2024 JSGeneratorObject::kContinuationOffset));
2028 EmitReturnIteratorResult(true); 2025 // Pop value from top-of-stack slot, box result into result register.
2026 EmitCreateIteratorResult(true);
2027 EmitUnwindBeforeReturn();
2028 EmitReturnSequence();
2029 break; 2029 break;
2030 } 2030 }
2031 2031
2032 case Yield::DELEGATING: { 2032 case Yield::DELEGATING: {
2033 VisitForStackValue(expr->generator_object()); 2033 VisitForStackValue(expr->generator_object());
2034 2034
2035 // Initial stack layout is as follows: 2035 // Initial stack layout is as follows:
2036 // [sp + 1 * kPointerSize] iter 2036 // [sp + 1 * kPointerSize] iter
2037 // [sp + 0 * kPointerSize] g 2037 // [sp + 0 * kPointerSize] g
2038 2038
2039 Label l_catch, l_try, l_resume, l_next, l_call, l_loop; 2039 Label l_catch, l_try, l_resume, l_next, l_call, l_loop;
2040 // Initial send value is undefined. 2040 // Initial send value is undefined.
2041 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 2041 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
2042 __ Branch(&l_next); 2042 __ Branch(&l_next);
2043 2043
2044 // catch (e) { receiver = iter; f = iter.throw; arg = e; goto l_call; } 2044 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2045 __ bind(&l_catch); 2045 __ bind(&l_catch);
2046 __ mov(a0, v0); 2046 __ mov(a0, v0);
2047 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2047 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2048 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
2048 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2049 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
2049 __ push(a3); // iter 2050 __ push(a3); // iter
2050 __ push(a0); // exception 2051 __ push(a0); // exception
2051 __ mov(a0, a3); // iter
2052 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
2053 Handle<Code> throw_ic = isolate()->builtins()->LoadIC_Initialize();
2054 CallIC(throw_ic); // iter.throw in a0
2055 __ mov(a0, v0);
2056 __ jmp(&l_call); 2052 __ jmp(&l_call);
2057 2053
2058 // try { received = yield result.value } 2054 // try { received = %yield result }
2055 // Shuffle the received result above a try handler and yield it without
2056 // re-boxing.
2059 __ bind(&l_try); 2057 __ bind(&l_try);
2060 __ pop(a0); // result.value 2058 __ pop(a0); // result
2061 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2059 __ PushTryHandler(StackHandler::CATCH, expr->index());
2062 const int handler_size = StackHandlerConstants::kSize; 2060 const int handler_size = StackHandlerConstants::kSize;
2063 __ push(a0); // result.value 2061 __ push(a0); // result
2064 __ lw(a3, MemOperand(sp, (0 + 1) * kPointerSize + handler_size)); // g 2062 __ lw(a3, MemOperand(sp, (0 + 1) * kPointerSize + handler_size)); // g
2065 __ push(a3); // g 2063 __ push(a3); // g
2066 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2064 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2067 __ mov(a0, v0); 2065 __ mov(a0, v0);
2068 __ lw(context_register(), 2066 __ lw(context_register(),
2069 MemOperand(fp, StandardFrameConstants::kContextOffset)); 2067 MemOperand(fp, StandardFrameConstants::kContextOffset));
2070 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2068 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2071 __ Branch(&l_resume, ne, a0, Operand(at)); 2069 __ Branch(&l_resume, ne, a0, Operand(at));
2072 EmitReturnIteratorResult(false); 2070 __ pop(v0); // result
2071 EmitReturnSequence();
2073 __ mov(a0, v0); 2072 __ mov(a0, v0);
2074 __ bind(&l_resume); // received in a0 2073 __ bind(&l_resume); // received in a0
2075 __ PopTryHandler(); 2074 __ PopTryHandler();
2076 2075
2077 // receiver = iter; f = iter.next; arg = received; 2076 // receiver = iter; f = 'next'; arg = received;
2078 __ bind(&l_next); 2077 __ bind(&l_next);
2078 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
2079 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2079 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
2080 __ push(a3); // iter 2080 __ push(a3); // iter
2081 __ push(a0); // received 2081 __ push(a0); // received
2082 __ mov(a0, a3); // iter
2083 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
2084 Handle<Code> next_ic = isolate()->builtins()->LoadIC_Initialize();
2085 CallIC(next_ic); // iter.next in a0
2086 __ mov(a0, v0);
2087 2082
2088 // result = f.call(receiver, arg); 2083 // result = receiver[f](arg);
2089 __ bind(&l_call); 2084 __ bind(&l_call);
2090 Label l_call_runtime; 2085 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
2091 __ JumpIfSmi(a0, &l_call_runtime); 2086 CallIC(ic);
2092 __ GetObjectType(a0, a1, a1);
2093 __ Branch(&l_call_runtime, ne, a1, Operand(JS_FUNCTION_TYPE));
2094 __ mov(a1, a0);
2095 ParameterCount count(1);
2096 __ InvokeFunction(a1, count, CALL_FUNCTION,
2097 NullCallWrapper(), CALL_AS_METHOD);
2098 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2087 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2099 __ jmp(&l_loop);
2100 __ bind(&l_call_runtime);
2101 __ push(a0);
2102 __ CallRuntime(Runtime::kCall, 3);
2103 2088
2104 // val = result.value; if (!result.done) goto l_try; 2089 // if (!result.done) goto l_try;
2105 __ bind(&l_loop); 2090 __ bind(&l_loop);
2106 __ mov(a0, v0); 2091 __ mov(a0, v0);
2107 // result.value
2108 __ push(a0); // save result 2092 __ push(a0); // save result
2109 __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value"
2110 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize();
2111 CallIC(value_ic); // result.value in a0
2112 __ mov(a0, v0);
2113 __ pop(a1); // result
2114 __ push(a0); // result.value
2115 __ mov(a0, a1); // result
2116 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" 2093 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done"
2117 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); 2094 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize();
2118 CallIC(done_ic); // result.done in v0 2095 CallIC(done_ic); // result.done in v0
2119 __ mov(a0, v0); 2096 __ mov(a0, v0);
2120 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2097 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2121 CallIC(bool_ic); 2098 CallIC(bool_ic);
2122 __ Branch(&l_try, eq, v0, Operand(zero_reg)); 2099 __ Branch(&l_try, eq, v0, Operand(zero_reg));
2123 2100
2124 // result.value 2101 // result.value
2125 __ pop(v0); // result.value 2102 __ pop(a0); // result
2103 __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value"
2104 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize();
2105 CallIC(value_ic); // result.value in v0
2126 context()->DropAndPlug(2, v0); // drop iter and g 2106 context()->DropAndPlug(2, v0); // drop iter and g
2127 break; 2107 break;
2128 } 2108 }
2129 } 2109 }
2130 } 2110 }
2131 2111
2132 2112
2133 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2113 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2134 Expression *value, 2114 Expression *value,
2135 JSGeneratorObject::ResumeMode resume_mode) { 2115 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 // Throw error if we attempt to operate on a running generator. 2199 // Throw error if we attempt to operate on a running generator.
2220 __ bind(&wrong_state); 2200 __ bind(&wrong_state);
2221 __ push(a1); 2201 __ push(a1);
2222 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2202 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2223 2203
2224 __ bind(&done); 2204 __ bind(&done);
2225 context()->Plug(result_register()); 2205 context()->Plug(result_register());
2226 } 2206 }
2227 2207
2228 2208
2229 void FullCodeGenerator::EmitReturnIteratorResult(bool done) { 2209 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2230 Label gc_required; 2210 Label gc_required;
2231 Label allocated; 2211 Label allocated;
2232 2212
2233 Handle<Map> map(isolate()->native_context()->generator_result_map()); 2213 Handle<Map> map(isolate()->native_context()->generator_result_map());
2234 2214
2235 __ Allocate(map->instance_size(), a0, a2, a3, &gc_required, TAG_OBJECT); 2215 __ Allocate(map->instance_size(), a0, a2, a3, &gc_required, TAG_OBJECT);
2216 __ jmp(&allocated);
2217
2218 __ bind(&gc_required);
2219 __ Push(Smi::FromInt(map->instance_size()));
2220 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
2221 __ lw(context_register(),
2222 MemOperand(fp, StandardFrameConstants::kContextOffset));
2236 2223
2237 __ bind(&allocated); 2224 __ bind(&allocated);
2238 __ li(a1, Operand(map)); 2225 __ li(a1, Operand(map));
2239 __ pop(a2); 2226 __ pop(a2);
2240 __ li(a3, Operand(isolate()->factory()->ToBoolean(done))); 2227 __ li(a3, Operand(isolate()->factory()->ToBoolean(done)));
2241 __ li(t0, Operand(isolate()->factory()->empty_fixed_array())); 2228 __ li(t0, Operand(isolate()->factory()->empty_fixed_array()));
2242 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); 2229 ASSERT_EQ(map->instance_size(), 5 * kPointerSize);
2243 __ sw(a1, FieldMemOperand(a0, HeapObject::kMapOffset)); 2230 __ sw(a1, FieldMemOperand(a0, HeapObject::kMapOffset));
2244 __ sw(t0, FieldMemOperand(a0, JSObject::kPropertiesOffset)); 2231 __ sw(t0, FieldMemOperand(a0, JSObject::kPropertiesOffset));
2245 __ sw(t0, FieldMemOperand(a0, JSObject::kElementsOffset)); 2232 __ sw(t0, FieldMemOperand(a0, JSObject::kElementsOffset));
2246 __ sw(a2, 2233 __ sw(a2,
2247 FieldMemOperand(a0, JSGeneratorObject::kResultValuePropertyOffset)); 2234 FieldMemOperand(a0, JSGeneratorObject::kResultValuePropertyOffset));
2248 __ sw(a3, 2235 __ sw(a3,
2249 FieldMemOperand(a0, JSGeneratorObject::kResultDonePropertyOffset)); 2236 FieldMemOperand(a0, JSGeneratorObject::kResultDonePropertyOffset));
2250 2237
2251 // Only the value field needs a write barrier, as the other values are in the 2238 // Only the value field needs a write barrier, as the other values are in the
2252 // root set. 2239 // root set.
2253 __ RecordWriteField(a0, JSGeneratorObject::kResultValuePropertyOffset, 2240 __ RecordWriteField(a0, JSGeneratorObject::kResultValuePropertyOffset,
2254 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); 2241 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs);
2255
2256 if (done) {
2257 // Exit all nested statements.
2258 NestedStatement* current = nesting_stack_;
2259 int stack_depth = 0;
2260 int context_length = 0;
2261 while (current != NULL) {
2262 current = current->Exit(&stack_depth, &context_length);
2263 }
2264 __ Drop(stack_depth);
2265 }
2266
2267 __ mov(result_register(), a0); 2242 __ mov(result_register(), a0);
2268 EmitReturnSequence();
2269
2270 __ bind(&gc_required);
2271 __ Push(Smi::FromInt(map->instance_size()));
2272 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
2273 __ lw(context_register(),
2274 MemOperand(fp, StandardFrameConstants::kContextOffset));
2275 __ jmp(&allocated);
2276 } 2243 }
2277 2244
2278 2245
2279 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2246 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2280 SetSourcePosition(prop->position()); 2247 SetSourcePosition(prop->position());
2281 Literal* key = prop->key()->AsLiteral(); 2248 Literal* key = prop->key()->AsLiteral();
2282 __ mov(a0, result_register()); 2249 __ mov(a0, result_register());
2283 __ li(a2, Operand(key->handle())); 2250 __ li(a2, Operand(key->handle()));
2284 // Call load IC. It has arguments receiver and property name a0 and a2. 2251 // Call load IC. It has arguments receiver and property name a0 and a2.
2285 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2252 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 VisitForStackValue(args->at(i)); 2671 VisitForStackValue(args->at(i));
2705 } 2672 }
2706 } 2673 }
2707 // Record source position for debugger. 2674 // Record source position for debugger.
2708 SetSourcePosition(expr->position()); 2675 SetSourcePosition(expr->position());
2709 2676
2710 // Record call targets. 2677 // Record call targets.
2711 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); 2678 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
2712 Handle<Object> uninitialized = 2679 Handle<Object> uninitialized =
2713 TypeFeedbackCells::UninitializedSentinel(isolate()); 2680 TypeFeedbackCells::UninitializedSentinel(isolate());
2714 Handle<JSGlobalPropertyCell> cell = 2681 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
2715 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
2716 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); 2682 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
2717 __ li(a2, Operand(cell)); 2683 __ li(a2, Operand(cell));
2718 2684
2719 CallFunctionStub stub(arg_count, flags); 2685 CallFunctionStub stub(arg_count, flags);
2720 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2686 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2721 __ CallStub(&stub, expr->CallFeedbackId()); 2687 __ CallStub(&stub, expr->CallFeedbackId());
2722 RecordJSReturnSite(expr); 2688 RecordJSReturnSite(expr);
2723 // Restore context register. 2689 // Restore context register.
2724 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2690 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2725 context()->DropAndPlug(1, v0); 2691 context()->DropAndPlug(1, v0);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2899 // constructor invocation. 2865 // constructor invocation.
2900 SetSourcePosition(expr->position()); 2866 SetSourcePosition(expr->position());
2901 2867
2902 // Load function and argument count into a1 and a0. 2868 // Load function and argument count into a1 and a0.
2903 __ li(a0, Operand(arg_count)); 2869 __ li(a0, Operand(arg_count));
2904 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2870 __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
2905 2871
2906 // Record call targets in unoptimized code. 2872 // Record call targets in unoptimized code.
2907 Handle<Object> uninitialized = 2873 Handle<Object> uninitialized =
2908 TypeFeedbackCells::UninitializedSentinel(isolate()); 2874 TypeFeedbackCells::UninitializedSentinel(isolate());
2909 Handle<JSGlobalPropertyCell> cell = 2875 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
2910 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
2911 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); 2876 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
2912 __ li(a2, Operand(cell)); 2877 __ li(a2, Operand(cell));
2913 2878
2914 CallConstructStub stub(RECORD_CALL_TARGET); 2879 CallConstructStub stub(RECORD_CALL_TARGET);
2915 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2880 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2916 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2881 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2917 context()->Plug(v0); 2882 context()->Plug(v0);
2918 } 2883 }
2919 2884
2920 2885
(...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after
4962 *context_length = 0; 4927 *context_length = 0;
4963 return previous_; 4928 return previous_;
4964 } 4929 }
4965 4930
4966 4931
4967 #undef __ 4932 #undef __
4968 4933
4969 } } // namespace v8::internal 4934 } } // namespace v8::internal
4970 4935
4971 #endif // V8_TARGET_ARCH_MIPS 4936 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698