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

Side by Side Diff: src/ia32/full-codegen-ia32.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/ia32/code-stubs-ia32.cc ('k') | src/ia32/ic-ia32.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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // o esi: our context 111 // o esi: our context
112 // o ebp: our caller's frame pointer 112 // o ebp: our caller's frame pointer
113 // o esp: stack pointer (pointing to return address) 113 // o esp: stack pointer (pointing to return address)
114 // 114 //
115 // The function builds a JS frame. Please see JavaScriptFrameConstants in 115 // The function builds a JS frame. Please see JavaScriptFrameConstants in
116 // frames-ia32.h for its layout. 116 // frames-ia32.h for its layout.
117 void FullCodeGenerator::Generate() { 117 void FullCodeGenerator::Generate() {
118 CompilationInfo* info = info_; 118 CompilationInfo* info = info_;
119 handler_table_ = 119 handler_table_ =
120 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 120 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
121 profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell( 121 profiling_counter_ = isolate()->factory()->NewCell(
122 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 122 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
123 SetFunctionPosition(function()); 123 SetFunctionPosition(function());
124 Comment cmnt(masm_, "[ function compiled by full code generator"); 124 Comment cmnt(masm_, "[ function compiled by full code generator");
125 125
126 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 126 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
127 127
128 #ifdef DEBUG 128 #ifdef DEBUG
129 if (strlen(FLAG_stop_at) > 0 && 129 if (strlen(FLAG_stop_at) > 0 &&
130 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 130 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
131 __ int3(); 131 __ int3();
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 } 308 }
309 309
310 310
311 void FullCodeGenerator::ClearAccumulator() { 311 void FullCodeGenerator::ClearAccumulator() {
312 __ Set(eax, Immediate(Smi::FromInt(0))); 312 __ Set(eax, Immediate(Smi::FromInt(0)));
313 } 313 }
314 314
315 315
316 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { 316 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
317 __ mov(ebx, Immediate(profiling_counter_)); 317 __ mov(ebx, Immediate(profiling_counter_));
318 __ sub(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), 318 __ sub(FieldOperand(ebx, Cell::kValueOffset),
319 Immediate(Smi::FromInt(delta))); 319 Immediate(Smi::FromInt(delta)));
320 } 320 }
321 321
322 322
323 void FullCodeGenerator::EmitProfilingCounterReset() { 323 void FullCodeGenerator::EmitProfilingCounterReset() {
324 int reset_value = FLAG_interrupt_budget; 324 int reset_value = FLAG_interrupt_budget;
325 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) { 325 if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) {
326 // Self-optimization is a one-off thing: if it fails, don't try again. 326 // Self-optimization is a one-off thing: if it fails, don't try again.
327 reset_value = Smi::kMaxValue; 327 reset_value = Smi::kMaxValue;
328 } 328 }
329 __ mov(ebx, Immediate(profiling_counter_)); 329 __ mov(ebx, Immediate(profiling_counter_));
330 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), 330 __ mov(FieldOperand(ebx, Cell::kValueOffset),
331 Immediate(Smi::FromInt(reset_value))); 331 Immediate(Smi::FromInt(reset_value)));
332 } 332 }
333 333
334 334
335 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, 335 void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
336 Label* back_edge_target) { 336 Label* back_edge_target) {
337 Comment cmnt(masm_, "[ Back edge bookkeeping"); 337 Comment cmnt(masm_, "[ Back edge bookkeeping");
338 Label ok; 338 Label ok;
339 339
340 int weight = 1; 340 int weight = 1;
341 if (FLAG_weighted_back_edges) { 341 if (FLAG_weighted_back_edges) {
342 ASSERT(back_edge_target->is_bound()); 342 ASSERT(back_edge_target->is_bound());
343 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); 343 int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
344 weight = Min(kMaxBackEdgeWeight, 344 weight = Min(kMaxBackEdgeWeight,
345 Max(1, distance / kBackEdgeDistanceUnit)); 345 Max(1, distance / kCodeSizeMultiplier));
346 } 346 }
347 EmitProfilingCounterDecrement(weight); 347 EmitProfilingCounterDecrement(weight);
348 __ j(positive, &ok, Label::kNear); 348 __ j(positive, &ok, Label::kNear);
349 InterruptStub stub; 349 InterruptStub stub;
350 __ CallStub(&stub); 350 __ CallStub(&stub);
351 351
352 // Record a mapping of this PC offset to the OSR id. This is used to find 352 // Record a mapping of this PC offset to the OSR id. This is used to find
353 // the AST id from the unoptimized code in order to use it as a key into 353 // the AST id from the unoptimized code in order to use it as a key into
354 // the deoptimization input data found in the optimized code. 354 // the deoptimization input data found in the optimized code.
355 RecordBackEdge(stmt->OsrEntryId()); 355 RecordBackEdge(stmt->OsrEntryId());
(...skipping 21 matching lines...) Expand all
377 __ CallRuntime(Runtime::kTraceExit, 1); 377 __ CallRuntime(Runtime::kTraceExit, 1);
378 } 378 }
379 if (FLAG_interrupt_at_exit || FLAG_self_optimization) { 379 if (FLAG_interrupt_at_exit || FLAG_self_optimization) {
380 // Pretend that the exit is a backwards jump to the entry. 380 // Pretend that the exit is a backwards jump to the entry.
381 int weight = 1; 381 int weight = 1;
382 if (info_->ShouldSelfOptimize()) { 382 if (info_->ShouldSelfOptimize()) {
383 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 383 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
384 } else if (FLAG_weighted_back_edges) { 384 } else if (FLAG_weighted_back_edges) {
385 int distance = masm_->pc_offset(); 385 int distance = masm_->pc_offset();
386 weight = Min(kMaxBackEdgeWeight, 386 weight = Min(kMaxBackEdgeWeight,
387 Max(1, distance / kBackEdgeDistanceUnit)); 387 Max(1, distance / kCodeSizeMultiplier));
388 } 388 }
389 EmitProfilingCounterDecrement(weight); 389 EmitProfilingCounterDecrement(weight);
390 Label ok; 390 Label ok;
391 __ j(positive, &ok, Label::kNear); 391 __ j(positive, &ok, Label::kNear);
392 __ push(eax); 392 __ push(eax);
393 if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) { 393 if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) {
394 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 394 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
395 __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1); 395 __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1);
396 } else { 396 } else {
397 InterruptStub stub; 397 InterruptStub stub;
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 __ jmp(&loop); 1098 __ jmp(&loop);
1099 1099
1100 __ bind(&no_descriptors); 1100 __ bind(&no_descriptors);
1101 __ add(esp, Immediate(kPointerSize)); 1101 __ add(esp, Immediate(kPointerSize));
1102 __ jmp(&exit); 1102 __ jmp(&exit);
1103 1103
1104 // We got a fixed array in register eax. Iterate through that. 1104 // We got a fixed array in register eax. Iterate through that.
1105 Label non_proxy; 1105 Label non_proxy;
1106 __ bind(&fixed_array); 1106 __ bind(&fixed_array);
1107 1107
1108 Handle<JSGlobalPropertyCell> cell = 1108 Handle<Cell> cell = isolate()->factory()->NewCell(
1109 isolate()->factory()->NewJSGlobalPropertyCell( 1109 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
1110 Handle<Object>( 1110 isolate()));
1111 Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
1112 isolate()));
1113 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); 1111 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
1114 __ LoadHeapObject(ebx, cell); 1112 __ LoadHeapObject(ebx, cell);
1115 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), 1113 __ mov(FieldOperand(ebx, Cell::kValueOffset),
1116 Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); 1114 Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
1117 1115
1118 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check 1116 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check
1119 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object 1117 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object
1120 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1118 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1121 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); 1119 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx);
1122 __ j(above, &non_proxy); 1120 __ j(above, &non_proxy);
1123 __ mov(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy 1121 __ mov(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy
1124 __ bind(&non_proxy); 1122 __ bind(&non_proxy);
1125 __ push(ebx); // Smi 1123 __ push(ebx); // Smi
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
1783 for (int i = 0; i < length; i++) { 1781 for (int i = 0; i < length; i++) {
1784 Expression* subexpr = subexprs->at(i); 1782 Expression* subexpr = subexprs->at(i);
1785 // If the subexpression is a literal or a simple materialized literal it 1783 // If the subexpression is a literal or a simple materialized literal it
1786 // is already set in the cloned array. 1784 // is already set in the cloned array.
1787 if (subexpr->AsLiteral() != NULL || 1785 if (subexpr->AsLiteral() != NULL ||
1788 CompileTimeValue::IsCompileTimeValue(subexpr)) { 1786 CompileTimeValue::IsCompileTimeValue(subexpr)) {
1789 continue; 1787 continue;
1790 } 1788 }
1791 1789
1792 if (!result_saved) { 1790 if (!result_saved) {
1793 __ push(eax); 1791 __ push(eax); // array literal.
1792 __ push(Immediate(Smi::FromInt(expr->literal_index())));
1794 result_saved = true; 1793 result_saved = true;
1795 } 1794 }
1796 VisitForAccumulatorValue(subexpr); 1795 VisitForAccumulatorValue(subexpr);
1797 1796
1798 if (IsFastObjectElementsKind(constant_elements_kind)) { 1797 if (IsFastObjectElementsKind(constant_elements_kind)) {
1799 // Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they 1798 // Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they
1800 // cannot transition and don't need to call the runtime stub. 1799 // cannot transition and don't need to call the runtime stub.
1801 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1800 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
1802 __ mov(ebx, Operand(esp, 0)); // Copy of array literal. 1801 __ mov(ebx, Operand(esp, kPointerSize)); // Copy of array literal.
1803 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); 1802 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
1804 // Store the subexpression value in the array's elements. 1803 // Store the subexpression value in the array's elements.
1805 __ mov(FieldOperand(ebx, offset), result_register()); 1804 __ mov(FieldOperand(ebx, offset), result_register());
1806 // Update the write barrier for the array store. 1805 // Update the write barrier for the array store.
1807 __ RecordWriteField(ebx, offset, result_register(), ecx, 1806 __ RecordWriteField(ebx, offset, result_register(), ecx,
1808 kDontSaveFPRegs, 1807 kDontSaveFPRegs,
1809 EMIT_REMEMBERED_SET, 1808 EMIT_REMEMBERED_SET,
1810 INLINE_SMI_CHECK); 1809 INLINE_SMI_CHECK);
1811 } else { 1810 } else {
1812 // Store the subexpression value in the array's elements. 1811 // Store the subexpression value in the array's elements.
1813 __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
1814 __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset));
1815 __ mov(ecx, Immediate(Smi::FromInt(i))); 1812 __ mov(ecx, Immediate(Smi::FromInt(i)));
1816 __ mov(edx, Immediate(Smi::FromInt(expr->literal_index())));
1817 StoreArrayLiteralElementStub stub; 1813 StoreArrayLiteralElementStub stub;
1818 __ CallStub(&stub); 1814 __ CallStub(&stub);
1819 } 1815 }
1820 1816
1821 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1817 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
1822 } 1818 }
1823 1819
1824 if (result_saved) { 1820 if (result_saved) {
1821 __ add(esp, Immediate(kPointerSize)); // literal index
1825 context()->PlugTOS(); 1822 context()->PlugTOS();
1826 } else { 1823 } else {
1827 context()->Plug(eax); 1824 context()->Plug(eax);
1828 } 1825 }
1829 } 1826 }
1830 1827
1831 1828
1832 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1829 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1833 Comment cmnt(masm_, "[ Assignment"); 1830 Comment cmnt(masm_, "[ Assignment");
1834 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 1831 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1943 } 1940 }
1944 1941
1945 1942
1946 void FullCodeGenerator::VisitYield(Yield* expr) { 1943 void FullCodeGenerator::VisitYield(Yield* expr) {
1947 Comment cmnt(masm_, "[ Yield"); 1944 Comment cmnt(masm_, "[ Yield");
1948 // Evaluate yielded value first; the initial iterator definition depends on 1945 // Evaluate yielded value first; the initial iterator definition depends on
1949 // this. It stays on the stack while we update the iterator. 1946 // this. It stays on the stack while we update the iterator.
1950 VisitForStackValue(expr->expression()); 1947 VisitForStackValue(expr->expression());
1951 1948
1952 switch (expr->yield_kind()) { 1949 switch (expr->yield_kind()) {
1953 case Yield::INITIAL: 1950 case Yield::SUSPEND:
1954 case Yield::SUSPEND: { 1951 // Pop value from top-of-stack slot; box result into result register.
1952 EmitCreateIteratorResult(false);
1953 __ push(result_register());
1954 // Fall through.
1955 case Yield::INITIAL: {
1955 VisitForStackValue(expr->generator_object()); 1956 VisitForStackValue(expr->generator_object());
1956 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1957 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1957 __ mov(context_register(), 1958 __ mov(context_register(),
1958 Operand(ebp, StandardFrameConstants::kContextOffset)); 1959 Operand(ebp, StandardFrameConstants::kContextOffset));
1959 1960
1960 Label resume; 1961 Label resume;
1961 __ CompareRoot(result_register(), Heap::kTheHoleValueRootIndex); 1962 __ CompareRoot(result_register(), Heap::kTheHoleValueRootIndex);
1962 __ j(not_equal, &resume); 1963 __ j(not_equal, &resume);
1963 if (expr->yield_kind() == Yield::SUSPEND) { 1964 __ pop(result_register());
1964 EmitReturnIteratorResult(false); 1965 EmitReturnSequence();
1965 } else {
1966 __ pop(result_register());
1967 EmitReturnSequence();
1968 }
1969 1966
1970 __ bind(&resume); 1967 __ bind(&resume);
1971 context()->Plug(result_register()); 1968 context()->Plug(result_register());
1972 break; 1969 break;
1973 } 1970 }
1974 1971
1975 case Yield::FINAL: { 1972 case Yield::FINAL: {
1976 VisitForAccumulatorValue(expr->generator_object()); 1973 VisitForAccumulatorValue(expr->generator_object());
1977 __ mov(FieldOperand(result_register(), 1974 __ mov(FieldOperand(result_register(),
1978 JSGeneratorObject::kContinuationOffset), 1975 JSGeneratorObject::kContinuationOffset),
1979 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); 1976 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
1980 EmitReturnIteratorResult(true); 1977 // Pop value from top-of-stack slot, box result into result register.
1978 EmitCreateIteratorResult(true);
1979 EmitUnwindBeforeReturn();
1980 EmitReturnSequence();
1981 break; 1981 break;
1982 } 1982 }
1983 1983
1984 case Yield::DELEGATING: { 1984 case Yield::DELEGATING: {
1985 VisitForStackValue(expr->generator_object()); 1985 VisitForStackValue(expr->generator_object());
1986 1986
1987 // Initial stack layout is as follows: 1987 // Initial stack layout is as follows:
1988 // [sp + 1 * kPointerSize] iter 1988 // [sp + 1 * kPointerSize] iter
1989 // [sp + 0 * kPointerSize] g 1989 // [sp + 0 * kPointerSize] g
1990 1990
1991 Label l_catch, l_try, l_resume, l_next, l_call, l_loop; 1991 Label l_catch, l_try, l_resume, l_next, l_call, l_loop;
1992 // Initial send value is undefined. 1992 // Initial send value is undefined.
1993 __ mov(eax, isolate()->factory()->undefined_value()); 1993 __ mov(eax, isolate()->factory()->undefined_value());
1994 __ jmp(&l_next); 1994 __ jmp(&l_next);
1995 1995
1996 // catch (e) { receiver = iter; f = iter.throw; arg = e; goto l_call; } 1996 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
1997 __ bind(&l_catch); 1997 __ bind(&l_catch);
1998 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 1998 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
1999 __ mov(edx, Operand(esp, 1 * kPointerSize)); // iter 1999 __ mov(ecx, isolate()->factory()->throw_string()); // "throw"
2000 __ push(edx); // iter 2000 __ push(ecx); // "throw"
2001 __ push(Operand(esp, 2 * kPointerSize)); // iter
2001 __ push(eax); // exception 2002 __ push(eax); // exception
2002 __ mov(ecx, isolate()->factory()->throw_string()); // "throw"
2003 Handle<Code> throw_ic = isolate()->builtins()->LoadIC_Initialize();
2004 CallIC(throw_ic); // iter.throw in eax
2005 __ jmp(&l_call); 2003 __ jmp(&l_call);
2006 2004
2007 // try { received = yield result.value } 2005 // try { received = %yield result }
2006 // Shuffle the received result above a try handler and yield it without
2007 // re-boxing.
2008 __ bind(&l_try); 2008 __ bind(&l_try);
2009 __ pop(eax); // result.value 2009 __ pop(eax); // result
2010 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2010 __ PushTryHandler(StackHandler::CATCH, expr->index());
2011 const int handler_size = StackHandlerConstants::kSize; 2011 const int handler_size = StackHandlerConstants::kSize;
2012 __ push(eax); // result.value 2012 __ push(eax); // result
2013 __ push(Operand(esp, (0 + 1) * kPointerSize + handler_size)); // g 2013 __ push(Operand(esp, (0 + 1) * kPointerSize + handler_size)); // g
2014 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2014 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2015 __ mov(context_register(), 2015 __ mov(context_register(),
2016 Operand(ebp, StandardFrameConstants::kContextOffset)); 2016 Operand(ebp, StandardFrameConstants::kContextOffset));
2017 __ CompareRoot(eax, Heap::kTheHoleValueRootIndex); 2017 __ CompareRoot(eax, Heap::kTheHoleValueRootIndex);
2018 __ j(not_equal, &l_resume); 2018 __ j(not_equal, &l_resume);
2019 EmitReturnIteratorResult(false); 2019 __ pop(eax); // result
2020 EmitReturnSequence();
2020 __ bind(&l_resume); // received in eax 2021 __ bind(&l_resume); // received in eax
2021 __ PopTryHandler(); 2022 __ PopTryHandler();
2022 2023
2023 // receiver = iter; f = iter.next; arg = received; 2024 // receiver = iter; f = iter.next; arg = received;
2024 __ bind(&l_next); 2025 __ bind(&l_next);
2025 __ mov(edx, Operand(esp, 1 * kPointerSize)); // iter 2026 __ mov(ecx, isolate()->factory()->next_string()); // "next"
2026 __ push(edx); // iter 2027 __ push(ecx);
2028 __ push(Operand(esp, 2 * kPointerSize)); // iter
2027 __ push(eax); // received 2029 __ push(eax); // received
2028 __ mov(ecx, isolate()->factory()->next_string()); // "next"
2029 Handle<Code> next_ic = isolate()->builtins()->LoadIC_Initialize();
2030 CallIC(next_ic); // iter.next in eax
2031 2030
2032 // result = f.call(receiver, arg); 2031 // result = receiver[f](arg);
2033 __ bind(&l_call); 2032 __ bind(&l_call);
2034 Label l_call_runtime; 2033 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
2035 __ JumpIfSmi(eax, &l_call_runtime); 2034 CallIC(ic);
2036 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
2037 __ j(not_equal, &l_call_runtime);
2038 __ mov(edi, eax);
2039 ParameterCount count(1);
2040 __ InvokeFunction(edi, count, CALL_FUNCTION,
2041 NullCallWrapper(), CALL_AS_METHOD);
2042 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2035 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2043 __ jmp(&l_loop); 2036 __ Drop(1); // The key is still on the stack; drop it.
2044 __ bind(&l_call_runtime);
2045 __ push(eax);
2046 __ CallRuntime(Runtime::kCall, 3);
2047 2037
2048 // val = result.value; if (!result.done) goto l_try; 2038 // if (!result.done) goto l_try;
2049 __ bind(&l_loop); 2039 __ bind(&l_loop);
2050 // result.value
2051 __ push(eax); // save result 2040 __ push(eax); // save result
2052 __ mov(edx, eax); // result 2041 __ mov(edx, eax); // result
2053 __ mov(ecx, isolate()->factory()->value_string()); // "value"
2054 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize();
2055 CallIC(value_ic); // result.value in eax
2056 __ pop(ebx); // result
2057 __ push(eax); // result.value
2058 __ mov(edx, ebx); // result
2059 __ mov(ecx, isolate()->factory()->done_string()); // "done" 2042 __ mov(ecx, isolate()->factory()->done_string()); // "done"
2060 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); 2043 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize();
2061 CallIC(done_ic); // result.done in eax 2044 CallIC(done_ic); // result.done in eax
2062 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2045 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2063 CallIC(bool_ic); 2046 CallIC(bool_ic);
2064 __ test(eax, eax); 2047 __ test(eax, eax);
2065 __ j(zero, &l_try); 2048 __ j(zero, &l_try);
2066 2049
2067 // result.value 2050 // result.value
2068 __ pop(eax); // result.value 2051 __ pop(edx); // result
2052 __ mov(ecx, isolate()->factory()->value_string()); // "value"
2053 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize();
2054 CallIC(value_ic); // result.value in eax
2069 context()->DropAndPlug(2, eax); // drop iter and g 2055 context()->DropAndPlug(2, eax); // drop iter and g
2070 break; 2056 break;
2071 } 2057 }
2072 } 2058 }
2073 } 2059 }
2074 2060
2075 2061
2076 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2062 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
2077 Expression *value, 2063 Expression *value,
2078 JSGeneratorObject::ResumeMode resume_mode) { 2064 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 // Throw error if we attempt to operate on a running generator. 2148 // Throw error if we attempt to operate on a running generator.
2163 __ bind(&wrong_state); 2149 __ bind(&wrong_state);
2164 __ push(ebx); 2150 __ push(ebx);
2165 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2151 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2166 2152
2167 __ bind(&done); 2153 __ bind(&done);
2168 context()->Plug(result_register()); 2154 context()->Plug(result_register());
2169 } 2155 }
2170 2156
2171 2157
2172 void FullCodeGenerator::EmitReturnIteratorResult(bool done) { 2158 void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
2173 Label gc_required; 2159 Label gc_required;
2174 Label allocated; 2160 Label allocated;
2175 2161
2176 Handle<Map> map(isolate()->native_context()->generator_result_map()); 2162 Handle<Map> map(isolate()->native_context()->generator_result_map());
2177 2163
2178 __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT); 2164 __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT);
2165 __ jmp(&allocated);
2166
2167 __ bind(&gc_required);
2168 __ Push(Smi::FromInt(map->instance_size()));
2169 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
2170 __ mov(context_register(),
2171 Operand(ebp, StandardFrameConstants::kContextOffset));
2179 2172
2180 __ bind(&allocated); 2173 __ bind(&allocated);
2181 __ mov(ebx, map); 2174 __ mov(ebx, map);
2182 __ pop(ecx); 2175 __ pop(ecx);
2183 __ mov(edx, isolate()->factory()->ToBoolean(done)); 2176 __ mov(edx, isolate()->factory()->ToBoolean(done));
2184 ASSERT_EQ(map->instance_size(), 5 * kPointerSize); 2177 ASSERT_EQ(map->instance_size(), 5 * kPointerSize);
2185 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); 2178 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx);
2186 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 2179 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
2187 isolate()->factory()->empty_fixed_array()); 2180 isolate()->factory()->empty_fixed_array());
2188 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 2181 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
2189 isolate()->factory()->empty_fixed_array()); 2182 isolate()->factory()->empty_fixed_array());
2190 __ mov(FieldOperand(eax, JSGeneratorObject::kResultValuePropertyOffset), ecx); 2183 __ mov(FieldOperand(eax, JSGeneratorObject::kResultValuePropertyOffset), ecx);
2191 __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx); 2184 __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx);
2192 2185
2193 // Only the value field needs a write barrier, as the other values are in the 2186 // Only the value field needs a write barrier, as the other values are in the
2194 // root set. 2187 // root set.
2195 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, 2188 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset,
2196 ecx, edx, kDontSaveFPRegs); 2189 ecx, edx, kDontSaveFPRegs);
2197
2198 if (done) {
2199 // Exit all nested statements.
2200 NestedStatement* current = nesting_stack_;
2201 int stack_depth = 0;
2202 int context_length = 0;
2203 while (current != NULL) {
2204 current = current->Exit(&stack_depth, &context_length);
2205 }
2206 __ Drop(stack_depth);
2207 }
2208
2209 EmitReturnSequence();
2210
2211 __ bind(&gc_required);
2212 __ Push(Smi::FromInt(map->instance_size()));
2213 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
2214 __ mov(context_register(),
2215 Operand(ebp, StandardFrameConstants::kContextOffset));
2216 __ jmp(&allocated);
2217 } 2190 }
2218 2191
2219 2192
2220 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2193 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2221 SetSourcePosition(prop->position()); 2194 SetSourcePosition(prop->position());
2222 Literal* key = prop->key()->AsLiteral(); 2195 Literal* key = prop->key()->AsLiteral();
2223 ASSERT(!key->handle()->IsSmi()); 2196 ASSERT(!key->handle()->IsSmi());
2224 __ mov(ecx, Immediate(key->handle())); 2197 __ mov(ecx, Immediate(key->handle()));
2225 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2198 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2226 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); 2199 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
2630 VisitForStackValue(args->at(i)); 2603 VisitForStackValue(args->at(i));
2631 } 2604 }
2632 } 2605 }
2633 // Record source position for debugger. 2606 // Record source position for debugger.
2634 SetSourcePosition(expr->position()); 2607 SetSourcePosition(expr->position());
2635 2608
2636 // Record call targets in unoptimized code. 2609 // Record call targets in unoptimized code.
2637 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); 2610 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET);
2638 Handle<Object> uninitialized = 2611 Handle<Object> uninitialized =
2639 TypeFeedbackCells::UninitializedSentinel(isolate()); 2612 TypeFeedbackCells::UninitializedSentinel(isolate());
2640 Handle<JSGlobalPropertyCell> cell = 2613 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
2641 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
2642 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); 2614 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
2643 __ mov(ebx, cell); 2615 __ mov(ebx, cell);
2644 2616
2645 CallFunctionStub stub(arg_count, flags); 2617 CallFunctionStub stub(arg_count, flags);
2646 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2618 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2647 __ CallStub(&stub, expr->CallFeedbackId()); 2619 __ CallStub(&stub, expr->CallFeedbackId());
2648 2620
2649 RecordJSReturnSite(expr); 2621 RecordJSReturnSite(expr);
2650 // Restore context register. 2622 // Restore context register.
2651 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2623 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2815 // constructor invocation. 2787 // constructor invocation.
2816 SetSourcePosition(expr->position()); 2788 SetSourcePosition(expr->position());
2817 2789
2818 // Load function and argument count into edi and eax. 2790 // Load function and argument count into edi and eax.
2819 __ Set(eax, Immediate(arg_count)); 2791 __ Set(eax, Immediate(arg_count));
2820 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2792 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2821 2793
2822 // Record call targets in unoptimized code. 2794 // Record call targets in unoptimized code.
2823 Handle<Object> uninitialized = 2795 Handle<Object> uninitialized =
2824 TypeFeedbackCells::UninitializedSentinel(isolate()); 2796 TypeFeedbackCells::UninitializedSentinel(isolate());
2825 Handle<JSGlobalPropertyCell> cell = 2797 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
2826 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized);
2827 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); 2798 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
2828 __ mov(ebx, cell); 2799 __ mov(ebx, cell);
2829 2800
2830 CallConstructStub stub(RECORD_CALL_TARGET); 2801 CallConstructStub stub(RECORD_CALL_TARGET);
2831 __ call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2802 __ call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2832 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2803 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2833 context()->Plug(eax); 2804 context()->Plug(eax);
2834 } 2805 }
2835 2806
2836 2807
(...skipping 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after
4922 *stack_depth = 0; 4893 *stack_depth = 0;
4923 *context_length = 0; 4894 *context_length = 0;
4924 return previous_; 4895 return previous_;
4925 } 4896 }
4926 4897
4927 #undef __ 4898 #undef __
4928 4899
4929 } } // namespace v8::internal 4900 } } // namespace v8::internal
4930 4901
4931 #endif // V8_TARGET_ARCH_IA32 4902 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698