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

Side by Side Diff: src/arm/full-codegen-arm.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/arm/code-stubs-arm.cc ('k') | src/arm/ic-arm.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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // o fp: our caller's frame pointer 122 // o fp: our caller's frame pointer
123 // o sp: stack pointer 123 // o sp: stack pointer
124 // o lr: return address 124 // o lr: return address
125 // 125 //
126 // The function builds a JS frame. Please see JavaScriptFrameConstants in 126 // The function builds a JS frame. Please see JavaScriptFrameConstants in
127 // frames-arm.h for its layout. 127 // frames-arm.h for its layout.
128 void FullCodeGenerator::Generate() { 128 void FullCodeGenerator::Generate() {
129 CompilationInfo* info = info_; 129 CompilationInfo* info = info_;
130 handler_table_ = 130 handler_table_ =
131 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 131 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
132 profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell( 132 profiling_counter_ = isolate()->factory()->NewCell(
133 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 133 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
134 SetFunctionPosition(function()); 134 SetFunctionPosition(function());
135 Comment cmnt(masm_, "[ function compiled by full code generator"); 135 Comment cmnt(masm_, "[ function compiled by full code generator");
136 136
137 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 137 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
138 138
139 #ifdef DEBUG 139 #ifdef DEBUG
140 if (strlen(FLAG_stop_at) > 0 && 140 if (strlen(FLAG_stop_at) > 0 &&
141 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 141 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
142 __ stop("stop-at"); 142 __ stop("stop-at");
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 320 }
321 321
322 322
323 void FullCodeGenerator::ClearAccumulator() { 323 void FullCodeGenerator::ClearAccumulator() {
324 __ mov(r0, Operand(Smi::FromInt(0))); 324 __ mov(r0, Operand(Smi::FromInt(0)));
325 } 325 }
326 326
327 327
328 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { 328 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
329 __ mov(r2, Operand(profiling_counter_)); 329 __ mov(r2, Operand(profiling_counter_));
330 __ ldr(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset)); 330 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset));
331 __ sub(r3, r3, Operand(Smi::FromInt(delta)), SetCC); 331 __ sub(r3, r3, Operand(Smi::FromInt(delta)), SetCC);
332 __ str(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset)); 332 __ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
333 } 333 }
334 334
335 335
336 void FullCodeGenerator::EmitProfilingCounterReset() { 336 void FullCodeGenerator::EmitProfilingCounterReset() {
337 int reset_value = FLAG_interrupt_budget; 337 int reset_value = FLAG_interrupt_budget;
338 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) { 338 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) {
339 // Self-optimization is a one-off thing: if it fails, don't try again. 339 // Self-optimization is a one-off thing: if it fails, don't try again.
340 reset_value = Smi::kMaxValue; 340 reset_value = Smi::kMaxValue;
341 } 341 }
342 if (isolate()->IsDebuggerActive()) { 342 if (isolate()->IsDebuggerActive()) {
343 // Detect debug break requests as soon as possible. 343 // Detect debug break requests as soon as possible.
344 reset_value = FLAG_interrupt_budget >> 4; 344 reset_value = FLAG_interrupt_budget >> 4;
345 } 345 }
346 __ mov(r2, Operand(profiling_counter_)); 346 __ mov(r2, Operand(profiling_counter_));
347 __ mov(r3, Operand(Smi::FromInt(reset_value))); 347 __ mov(r3, Operand(Smi::FromInt(reset_value)));
348 __ str(r3, FieldMemOperand(r2, JSGlobalPropertyCell::kValueOffset)); 348 __ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
349 } 349 }
350 350
351 351
352 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, 352 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
353 Label* back_edge_target) { 353 Label* back_edge_target) {
354 Comment cmnt(masm_, "[ Back edge bookkeeping"); 354 Comment cmnt(masm_, "[ Back edge bookkeeping");
355 // Block literal pools whilst emitting back edge code. 355 // Block literal pools whilst emitting back edge code.
356 Assembler::BlockConstPoolScope block_const_pool(masm_); 356 Assembler::BlockConstPoolScope block_const_pool(masm_);
357 Label ok; 357 Label ok;
358 358
359 int weight = 1; 359 int weight = 1;
360 if (FLAG_weighted_back_edges) { 360 if (FLAG_weighted_back_edges) {
361 ASSERT(back_edge_target->is_bound()); 361 ASSERT(back_edge_target->is_bound());
362 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); 362 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
363 weight = Min(kMaxBackEdgeWeight, 363 weight = Min(kMaxBackEdgeWeight,
364 Max(1, distance / kBackEdgeDistanceUnit)); 364 Max(1, distance / kCodeSizeMultiplier));
365 } 365 }
366 EmitProfilingCounterDecrement(weight); 366 EmitProfilingCounterDecrement(weight);
367 __ b(pl, &ok); 367 __ b(pl, &ok);
368 InterruptStub stub; 368 InterruptStub stub;
369 __ CallStub(&stub); 369 __ CallStub(&stub);
370 370
371 // Record a mapping of this PC offset to the OSR id. This is used to find 371 // Record a mapping of this PC offset to the OSR id. This is used to find
372 // the AST id from the unoptimized code in order to use it as a key into 372 // the AST id from the unoptimized code in order to use it as a key into
373 // the deoptimization input data found in the optimized code. 373 // the deoptimization input data found in the optimized code.
374 RecordBackEdge(stmt->OsrEntryId()); 374 RecordBackEdge(stmt->OsrEntryId());
(...skipping 22 matching lines...) Expand all
397 __ CallRuntime(Runtime::kTraceExit, 1); 397 __ CallRuntime(Runtime::kTraceExit, 1);
398 } 398 }
399 if (FLAG_interrupt_at_exit || FLAG_self_optimization) { 399 if (FLAG_interrupt_at_exit || FLAG_self_optimization) {
400 // Pretend that the exit is a backwards jump to the entry. 400 // Pretend that the exit is a backwards jump to the entry.
401 int weight = 1; 401 int weight = 1;
402 if (info_->ShouldSelfOptimize()) { 402 if (info_->ShouldSelfOptimize()) {
403 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 403 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
404 } else if (FLAG_weighted_back_edges) { 404 } else if (FLAG_weighted_back_edges) {
405 int distance = masm_->pc_offset(); 405 int distance = masm_->pc_offset();
406 weight = Min(kMaxBackEdgeWeight, 406 weight = Min(kMaxBackEdgeWeight,
407 Max(1, distance / kBackEdgeDistanceUnit)); 407 Max(1, distance / kCodeSizeMultiplier));
408 } 408 }
409 EmitProfilingCounterDecrement(weight); 409 EmitProfilingCounterDecrement(weight);
410 Label ok; 410 Label ok;
411 __ b(pl, &ok); 411 __ b(pl, &ok);
412 __ push(r0); 412 __ push(r0);
413 if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) { 413 if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) {
414 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 414 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
415 __ push(r2); 415 __ push(r2);
416 __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1); 416 __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1);
417 } else { 417 } else {
(...skipping 739 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 r0. Iterate through that. 1163 // We got a fixed array in register r0. 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(r1, cell); 1171 __ LoadHeapObject(r1, cell);
1174 __ mov(r2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); 1172 __ mov(r2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
1175 __ str(r2, FieldMemOperand(r1, JSGlobalPropertyCell::kValueOffset)); 1173 __ str(r2, FieldMemOperand(r1, Cell::kValueOffset));
1176 1174
1177 __ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check 1175 __ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check
1178 __ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object 1176 __ ldr(r2, 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 __ CompareObjectType(r2, r3, r3, LAST_JS_PROXY_TYPE); 1178 __ CompareObjectType(r2, r3, r3, LAST_JS_PROXY_TYPE);
1181 __ b(gt, &non_proxy); 1179 __ b(gt, &non_proxy);
1182 __ mov(r1, Operand(Smi::FromInt(0))); // Zero indicates proxy 1180 __ mov(r1, Operand(Smi::FromInt(0))); // Zero indicates proxy
1183 __ bind(&non_proxy); 1181 __ bind(&non_proxy);
1184 __ Push(r1, r0); // Smi and array 1182 __ Push(r1, r0); // Smi and array
1185 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset)); 1183 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset));
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 Expression* subexpr = subexprs->at(i); 1829 Expression* subexpr = subexprs->at(i);
1832 // If the subexpression is a literal or a simple materialized literal it 1830 // If the subexpression is a literal or a simple materialized literal it
1833 // is already set in the cloned array. 1831 // is already set in the cloned array.
1834 if (subexpr->AsLiteral() != NULL || 1832 if (subexpr->AsLiteral() != NULL ||
1835 CompileTimeValue::IsCompileTimeValue(subexpr)) { 1833 CompileTimeValue::IsCompileTimeValue(subexpr)) {
1836 continue; 1834 continue;
1837 } 1835 }
1838 1836
1839 if (!result_saved) { 1837 if (!result_saved) {
1840 __ push(r0); 1838 __ push(r0);
1839 __ Push(Smi::FromInt(expr->literal_index()));
1841 result_saved = true; 1840 result_saved = true;
1842 } 1841 }
1843 VisitForAccumulatorValue(subexpr); 1842 VisitForAccumulatorValue(subexpr);
1844 1843
1845 if (IsFastObjectElementsKind(constant_elements_kind)) { 1844 if (IsFastObjectElementsKind(constant_elements_kind)) {
1846 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1845 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1847 __ ldr(r6, MemOperand(sp)); // Copy of array literal. 1846 __ ldr(r6, MemOperand(sp, kPointerSize)); // Copy of array literal.
1848 __ ldr(r1, FieldMemOperand(r6, JSObject::kElementsOffset)); 1847 __ ldr(r1, FieldMemOperand(r6, JSObject::kElementsOffset));
1849 __ str(result_register(), FieldMemOperand(r1, offset)); 1848 __ str(result_register(), FieldMemOperand(r1, offset));
1850 // Update the write barrier for the array store. 1849 // Update the write barrier for the array store.
1851 __ RecordWriteField(r1, offset, result_register(), r2, 1850 __ RecordWriteField(r1, offset, result_register(), r2,
1852 kLRHasBeenSaved, kDontSaveFPRegs, 1851 kLRHasBeenSaved, kDontSaveFPRegs,
1853 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); 1852 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
1854 } else { 1853 } else {
1855 __ ldr(r1, MemOperand(sp)); // Copy of array literal.
1856 __ ldr(r2, FieldMemOperand(r1, JSObject::kMapOffset));
1857 __ mov(r3, Operand(Smi::FromInt(i))); 1854 __ mov(r3, Operand(Smi::FromInt(i)));
1858 __ mov(r4, Operand(Smi::FromInt(expr->literal_index())));
1859 StoreArrayLiteralElementStub stub; 1855 StoreArrayLiteralElementStub stub;
1860 __ CallStub(&stub); 1856 __ CallStub(&stub);
1861 } 1857 }
1862 1858
1863 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1859 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1864 } 1860 }
1865 1861
1866 if (result_saved) { 1862 if (result_saved) {
1863 __ pop(); // literal index
1867 context()->PlugTOS(); 1864 context()->PlugTOS();
1868 } else { 1865 } else {
1869 context()->Plug(r0); 1866 context()->Plug(r0);
1870 } 1867 }
1871 } 1868 }
1872 1869
1873 1870
1874 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1871 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1875 Comment cmnt(masm_, "[ Assignment"); 1872 Comment cmnt(masm_, "[ Assignment");
1876 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 1873 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1984 } 1981 }
1985 1982
1986 1983
1987 void FullCodeGenerator::VisitYield(Yield* expr) { 1984 void FullCodeGenerator::VisitYield(Yield* expr) {
1988 Comment cmnt(masm_, "[ Yield"); 1985 Comment cmnt(masm_, "[ Yield");
1989 // Evaluate yielded value first; the initial iterator definition depends on 1986 // Evaluate yielded value first; the initial iterator definition depends on
1990 // this. It stays on the stack while we update the iterator. 1987 // this. It stays on the stack while we update the iterator.
1991 VisitForStackValue(expr->expression()); 1988 VisitForStackValue(expr->expression());
1992 1989
1993 switch (expr->yield_kind()) { 1990 switch (expr->yield_kind()) {
1994 case Yield::INITIAL: 1991 case Yield::SUSPEND:
1995 case Yield::SUSPEND: { 1992 // Pop value from top-of-stack slot; box result into result register.
1993 EmitCreateIteratorResult(false);
1994 __ push(result_register());
1995 // Fall through.
1996 case Yield::INITIAL: {
1996 VisitForStackValue(expr->generator_object()); 1997 VisitForStackValue(expr->generator_object());
1997 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1998 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1998 __ ldr(context_register(), 1999 __ ldr(context_register(),
1999 MemOperand(fp, StandardFrameConstants::kContextOffset)); 2000 MemOperand(fp, StandardFrameConstants::kContextOffset));
2000 2001
2001 Label resume; 2002 Label resume;
2002 __ CompareRoot(result_register(), Heap::kTheHoleValueRootIndex); 2003 __ CompareRoot(result_register(), Heap::kTheHoleValueRootIndex);
2003 __ b(ne, &resume); 2004 __ b(ne, &resume);
2004 if (expr->yield_kind() == Yield::SUSPEND) { 2005 __ pop(result_register());
2005 EmitReturnIteratorResult(false); 2006 EmitReturnSequence();
2006 } else {
2007 __ pop(result_register());
2008 EmitReturnSequence();
2009 }
2010 2007
2011 __ bind(&resume); 2008 __ bind(&resume);
2012 context()->Plug(result_register()); 2009 context()->Plug(result_register());
2013 break; 2010 break;
2014 } 2011 }
2015 2012
2016 case Yield::FINAL: { 2013 case Yield::FINAL: {
2017 VisitForAccumulatorValue(expr->generator_object()); 2014 VisitForAccumulatorValue(expr->generator_object());
2018 __ mov(r1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); 2015 __ mov(r1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
2019 __ str(r1, FieldMemOperand(result_register(), 2016 __ str(r1, FieldMemOperand(result_register(),
2020 JSGeneratorObject::kContinuationOffset)); 2017 JSGeneratorObject::kContinuationOffset));
2021 EmitReturnIteratorResult(true); 2018 // Pop value from top-of-stack slot, box result into result register.
2019 EmitCreateIteratorResult(true);
2020 EmitUnwindBeforeReturn();
2021 EmitReturnSequence();
2022 break; 2022 break;
2023 } 2023 }
2024 2024
2025 case Yield::DELEGATING: { 2025 case Yield::DELEGATING: {
2026 VisitForStackValue(expr->generator_object()); 2026 VisitForStackValue(expr->generator_object());
2027 2027
2028 // Initial stack layout is as follows: 2028 // Initial stack layout is as follows:
2029 // [sp + 1 * kPointerSize] iter 2029 // [sp + 1 * kPointerSize] iter
2030 // [sp + 0 * kPointerSize] g 2030 // [sp + 0 * kPointerSize] g
2031 2031
2032 Label l_catch, l_try, l_resume, l_next, l_call, l_loop; 2032 Label l_catch, l_try, l_resume, l_next, l_call, l_loop;
2033 // Initial send value is undefined. 2033 // Initial send value is undefined.
2034 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 2034 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2035 __ b(&l_next); 2035 __ b(&l_next);
2036 2036
2037 // catch (e) { receiver = iter; f = iter.throw; arg = e; goto l_call; } 2037 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2038 __ bind(&l_catch); 2038 __ bind(&l_catch);
2039 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2039 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2040 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw"
2040 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2041 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2041 __ push(r3); // iter 2042 __ push(r3); // iter
2042 __ push(r0); // exception 2043 __ push(r0); // exception
2043 __ mov(r0, r3); // iter
2044 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw"
2045 Handle<Code> throw_ic = isolate()->builtins()->LoadIC_Initialize();
2046 CallIC(throw_ic); // iter.throw in r0
2047 __ jmp(&l_call); 2044 __ jmp(&l_call);
2048 2045
2049 // try { received = yield result.value } 2046 // try { received = %yield result }
2047 // Shuffle the received result above a try handler and yield it without
2048 // re-boxing.
2050 __ bind(&l_try); 2049 __ bind(&l_try);
2051 __ pop(r0); // result.value 2050 __ pop(r0); // result
2052 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2051 __ PushTryHandler(StackHandler::CATCH, expr->index());
2053 const int handler_size = StackHandlerConstants::kSize; 2052 const int handler_size = StackHandlerConstants::kSize;
2054 __ push(r0); // result.value 2053 __ push(r0); // result
2055 __ ldr(r3, MemOperand(sp, (0 + 1) * kPointerSize + handler_size)); // g 2054 __ ldr(r3, MemOperand(sp, (0 + 1) * kPointerSize + handler_size)); // g
2056 __ push(r3); // g 2055 __ push(r3); // g
2057 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2056 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2058 __ ldr(context_register(), 2057 __ ldr(context_register(),
2059 MemOperand(fp, StandardFrameConstants::kContextOffset)); 2058 MemOperand(fp, StandardFrameConstants::kContextOffset));
2060 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); 2059 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
2061 __ b(ne, &l_resume); 2060 __ b(ne, &l_resume);
2062 EmitReturnIteratorResult(false); 2061 __ pop(r0); // result
2062 EmitReturnSequence();
2063 __ bind(&l_resume); // received in r0 2063 __ bind(&l_resume); // received in r0
2064 __ PopTryHandler(); 2064 __ PopTryHandler();
2065 2065
2066 // receiver = iter; f = iter.next; arg = received; 2066 // receiver = iter; f = 'next'; arg = received;
2067 __ bind(&l_next); 2067 __ bind(&l_next);
2068 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next"
2068 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2069 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2069 __ push(r3); // iter 2070 __ push(r3); // iter
2070 __ push(r0); // received 2071 __ push(r0); // received
2071 __ mov(r0, r3); // iter
2072 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next"
2073 Handle<Code> next_ic = isolate()->builtins()->LoadIC_Initialize();
2074 CallIC(next_ic); // iter.next in r0
2075 2072
2076 // result = f.call(receiver, arg); 2073 // result = receiver[f](arg);
2077 __ bind(&l_call); 2074 __ bind(&l_call);
2078 Label l_call_runtime; 2075 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
2079 __ JumpIfSmi(r0, &l_call_runtime); 2076 CallIC(ic);
2080 __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
2081 __ b(ne, &l_call_runtime);
2082 __ mov(r1, r0);
2083 ParameterCount count(1);
2084 __ InvokeFunction(r1, count, CALL_FUNCTION,
2085 NullCallWrapper(), CALL_AS_METHOD);
2086 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2077 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2087 __ jmp(&l_loop);
2088 __ bind(&l_call_runtime);
2089 __ push(r0);
2090 __ CallRuntime(Runtime::kCall, 3);
2091 2078
2092 // val = result.value; if (!result.done) goto l_try; 2079 // if (!result.done) goto l_try;
2093 __ bind(&l_loop); 2080 __ bind(&l_loop);
2094 // result.value
2095 __ push(r0); // save result 2081 __ push(r0); // save result
2096 __ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value"
2097 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize();
2098 CallIC(value_ic); // result.value in r0
2099 __ pop(r1); // result
2100 __ push(r0); // result.value
2101 __ mov(r0, r1); // result
2102 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" 2082 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done"
2103 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); 2083 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize();
2104 CallIC(done_ic); // result.done in r0 2084 CallIC(done_ic); // result.done in r0
2105 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2085 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2106 CallIC(bool_ic); 2086 CallIC(bool_ic);
2107 __ cmp(r0, Operand(0)); 2087 __ cmp(r0, Operand(0));
2108 __ b(eq, &l_try); 2088 __ b(eq, &l_try);
2109 2089
2110 // result.value 2090 // result.value
2111 __ pop(r0); // result.value 2091 __ pop(r0); // result
2092 __ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value"
2093 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize();
2094 CallIC(value_ic); // result.value in r0
2112 context()->DropAndPlug(2, r0); // drop iter and g 2095 context()->DropAndPlug(2, r0); // drop iter and g
2113 break; 2096 break;
2114 } 2097 }
2115 } 2098 }
2116 } 2099 }
2117 2100
2118 2101
2119 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2102 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2120 Expression *value, 2103 Expression *value,
2121 JSGeneratorObject::ResumeMode resume_mode) { 2104 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2207 // Throw error if we attempt to operate on a running generator. 2190 // Throw error if we attempt to operate on a running generator.
2208 __ bind(&wrong_state); 2191 __ bind(&wrong_state);
2209 __ push(r1); 2192 __ push(r1);
2210 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2193 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2211 2194
2212 __ bind(&done); 2195 __ bind(&done);
2213 context()->Plug(result_register()); 2196 context()->Plug(result_register());
2214 } 2197 }
2215 2198
2216 2199
2217 void FullCodeGenerator::EmitReturnIteratorResult(bool done) { 2200 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2218 Label gc_required; 2201 Label gc_required;
2219 Label allocated; 2202 Label allocated;
2220 2203
2221 Handle<Map> map(isolate()->native_context()->generator_result_map()); 2204 Handle<Map> map(isolate()->native_context()->generator_result_map());
2222 2205
2223 __ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT); 2206 __ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT);
2207 __ jmp(&allocated);
2208
2209 __ bind(&gc_required);
2210 __ Push(Smi::FromInt(map->instance_size()));
2211 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
2212 __ ldr(context_register(),
2213 MemOperand(fp, StandardFrameConstants::kContextOffset));
2224 2214
2225 __ bind(&allocated); 2215 __ bind(&allocated);
2226 __ mov(r1, Operand(map)); 2216 __ mov(r1, Operand(map));
2227 __ pop(r2); 2217 __ pop(r2);
2228 __ mov(r3, Operand(isolate()->factory()->ToBoolean(done))); 2218 __ mov(r3, Operand(isolate()->factory()->ToBoolean(done)));
2229 __ mov(r4, Operand(isolate()->factory()->empty_fixed_array())); 2219 __ mov(r4, Operand(isolate()->factory()->empty_fixed_array()));
2230 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); 2220 ASSERT_EQ(map->instance_size(), 5 * kPointerSize);
2231 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 2221 __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
2232 __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset)); 2222 __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset));
2233 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); 2223 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
2234 __ str(r2, 2224 __ str(r2,
2235 FieldMemOperand(r0, JSGeneratorObject::kResultValuePropertyOffset)); 2225 FieldMemOperand(r0, JSGeneratorObject::kResultValuePropertyOffset));
2236 __ str(r3, 2226 __ str(r3,
2237 FieldMemOperand(r0, JSGeneratorObject::kResultDonePropertyOffset)); 2227 FieldMemOperand(r0, JSGeneratorObject::kResultDonePropertyOffset));
2238 2228
2239 // Only the value field needs a write barrier, as the other values are in the 2229 // Only the value field needs a write barrier, as the other values are in the
2240 // root set. 2230 // root set.
2241 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, 2231 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset,
2242 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); 2232 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs);
2243
2244 if (done) {
2245 // Exit all nested statements.
2246 NestedStatement* current = nesting_stack_;
2247 int stack_depth = 0;
2248 int context_length = 0;
2249 while (current != NULL) {
2250 current = current->Exit(&stack_depth, &context_length);
2251 }
2252 __ Drop(stack_depth);
2253 }
2254
2255 EmitReturnSequence();
2256
2257 __ bind(&gc_required);
2258 __ Push(Smi::FromInt(map->instance_size()));
2259 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
2260 __ ldr(context_register(),
2261 MemOperand(fp, StandardFrameConstants::kContextOffset));
2262 __ jmp(&allocated);
2263 } 2233 }
2264 2234
2265 2235
2266 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2236 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2267 SetSourcePosition(prop->position()); 2237 SetSourcePosition(prop->position());
2268 Literal* key = prop->key()->AsLiteral(); 2238 Literal* key = prop->key()->AsLiteral();
2269 __ mov(r2, Operand(key->handle())); 2239 __ mov(r2, Operand(key->handle()));
2270 // Call load IC. It has arguments receiver and property name r0 and r2. 2240 // Call load IC. It has arguments receiver and property name r0 and r2.
2271 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2241 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2272 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); 2242 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 VisitForStackValue(args->at(i)); 2646 VisitForStackValue(args->at(i));
2677 } 2647 }
2678 } 2648 }
2679 // Record source position for debugger. 2649 // Record source position for debugger.
2680 SetSourcePosition(expr->position()); 2650 SetSourcePosition(expr->position());
2681 2651
2682 // Record call targets in unoptimized code. 2652 // Record call targets in unoptimized code.
2683 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); 2653 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
2684 Handle<Object> uninitialized = 2654 Handle<Object> uninitialized =
2685 TypeFeedbackCells::UninitializedSentinel(isolate()); 2655 TypeFeedbackCells::UninitializedSentinel(isolate());
2686 Handle<JSGlobalPropertyCell> cell = 2656 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
2687 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
2688 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); 2657 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
2689 __ mov(r2, Operand(cell)); 2658 __ mov(r2, Operand(cell));
2690 2659
2691 CallFunctionStub stub(arg_count, flags); 2660 CallFunctionStub stub(arg_count, flags);
2692 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2661 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2693 __ CallStub(&stub, expr->CallFeedbackId()); 2662 __ CallStub(&stub, expr->CallFeedbackId());
2694 RecordJSReturnSite(expr); 2663 RecordJSReturnSite(expr);
2695 // Restore context register. 2664 // Restore context register.
2696 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2665 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2697 context()->DropAndPlug(1, r0); 2666 context()->DropAndPlug(1, r0);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2872 // constructor invocation. 2841 // constructor invocation.
2873 SetSourcePosition(expr->position()); 2842 SetSourcePosition(expr->position());
2874 2843
2875 // Load function and argument count into r1 and r0. 2844 // Load function and argument count into r1 and r0.
2876 __ mov(r0, Operand(arg_count)); 2845 __ mov(r0, Operand(arg_count));
2877 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2846 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2878 2847
2879 // Record call targets in unoptimized code. 2848 // Record call targets in unoptimized code.
2880 Handle<Object> uninitialized = 2849 Handle<Object> uninitialized =
2881 TypeFeedbackCells::UninitializedSentinel(isolate()); 2850 TypeFeedbackCells::UninitializedSentinel(isolate());
2882 Handle<JSGlobalPropertyCell> cell = 2851 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
2883 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
2884 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); 2852 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
2885 __ mov(r2, Operand(cell)); 2853 __ mov(r2, Operand(cell));
2886 2854
2887 CallConstructStub stub(RECORD_CALL_TARGET); 2855 CallConstructStub stub(RECORD_CALL_TARGET);
2888 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2856 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2889 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2857 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2890 context()->Plug(r0); 2858 context()->Plug(r0);
2891 } 2859 }
2892 2860
2893 2861
(...skipping 2031 matching lines...) Expand 10 before | Expand all | Expand 10 after
4925 *context_length = 0; 4893 *context_length = 0;
4926 return previous_; 4894 return previous_;
4927 } 4895 }
4928 4896
4929 4897
4930 #undef __ 4898 #undef __
4931 4899
4932 } } // namespace v8::internal 4900 } } // namespace v8::internal
4933 4901
4934 #endif // V8_TARGET_ARCH_ARM 4902 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698