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

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

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 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/deoptimizer-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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 // o fp: our caller's frame pointer 123 // o fp: our caller's frame pointer
124 // o sp: stack pointer 124 // o sp: stack pointer
125 // o lr: return address 125 // o lr: return address
126 // 126 //
127 // The function builds a JS frame. Please see JavaScriptFrameConstants in 127 // The function builds a JS frame. Please see JavaScriptFrameConstants in
128 // frames-arm.h for its layout. 128 // frames-arm.h for its layout.
129 void FullCodeGenerator::Generate() { 129 void FullCodeGenerator::Generate() {
130 CompilationInfo* info = info_; 130 CompilationInfo* info = info_;
131 handler_table_ = 131 handler_table_ =
132 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 132 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
133
134 InitializeFeedbackVector();
135
133 profiling_counter_ = isolate()->factory()->NewCell( 136 profiling_counter_ = isolate()->factory()->NewCell(
134 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 137 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
135 SetFunctionPosition(function()); 138 SetFunctionPosition(function());
136 Comment cmnt(masm_, "[ function compiled by full code generator"); 139 Comment cmnt(masm_, "[ function compiled by full code generator");
137 140
138 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 141 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
139 142
140 #ifdef DEBUG 143 #ifdef DEBUG
141 if (strlen(FLAG_stop_at) > 0 && 144 if (strlen(FLAG_stop_at) > 0 &&
142 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 145 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 } 198 }
196 } 199 }
197 200
198 bool function_in_register = true; 201 bool function_in_register = true;
199 202
200 // Possibly allocate a local context. 203 // Possibly allocate a local context.
201 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 204 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
202 if (heap_slots > 0) { 205 if (heap_slots > 0) {
203 // Argument to NewContext is the function, which is still in r1. 206 // Argument to NewContext is the function, which is still in r1.
204 Comment cmnt(masm_, "[ Allocate context"); 207 Comment cmnt(masm_, "[ Allocate context");
205 __ push(r1);
206 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { 208 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
209 __ push(r1);
207 __ Push(info->scope()->GetScopeInfo()); 210 __ Push(info->scope()->GetScopeInfo());
208 __ CallRuntime(Runtime::kNewGlobalContext, 2); 211 __ CallRuntime(Runtime::kNewGlobalContext, 2);
209 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { 212 } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
210 FastNewContextStub stub(heap_slots); 213 FastNewContextStub stub(heap_slots);
211 __ CallStub(&stub); 214 __ CallStub(&stub);
212 } else { 215 } else {
216 __ push(r1);
213 __ CallRuntime(Runtime::kNewFunctionContext, 1); 217 __ CallRuntime(Runtime::kNewFunctionContext, 1);
214 } 218 }
215 function_in_register = false; 219 function_in_register = false;
216 // Context is returned in both r0 and cp. It replaces the context 220 // Context is returned in r0. It replaces the context passed to us.
217 // passed to us. It's saved in the stack and kept live in cp. 221 // It's saved in the stack and kept live in cp.
218 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 222 __ mov(cp, r0);
223 __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset));
219 // Copy any necessary parameters into the context. 224 // Copy any necessary parameters into the context.
220 int num_parameters = info->scope()->num_parameters(); 225 int num_parameters = info->scope()->num_parameters();
221 for (int i = 0; i < num_parameters; i++) { 226 for (int i = 0; i < num_parameters; i++) {
222 Variable* var = scope()->parameter(i); 227 Variable* var = scope()->parameter(i);
223 if (var->IsContextSlot()) { 228 if (var->IsContextSlot()) {
224 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 229 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
225 (num_parameters - 1 - i) * kPointerSize; 230 (num_parameters - 1 - i) * kPointerSize;
226 // Load parameter from stack. 231 // Load parameter from stack.
227 __ ldr(r0, MemOperand(fp, parameter_offset)); 232 __ ldr(r0, MemOperand(fp, parameter_offset));
228 // Store it in the context. 233 // Store it in the context.
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 if (false_label_ != fall_through_) __ b(false_label_); 664 if (false_label_ != fall_through_) __ b(false_label_);
660 } 665 }
661 } 666 }
662 667
663 668
664 void FullCodeGenerator::DoTest(Expression* condition, 669 void FullCodeGenerator::DoTest(Expression* condition,
665 Label* if_true, 670 Label* if_true,
666 Label* if_false, 671 Label* if_false,
667 Label* fall_through) { 672 Label* fall_through) {
668 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 673 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
669 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); 674 CallIC(ic, condition->test_id());
670 __ tst(result_register(), result_register()); 675 __ tst(result_register(), result_register());
671 Split(ne, if_true, if_false, fall_through); 676 Split(ne, if_true, if_false, fall_through);
672 } 677 }
673 678
674 679
675 void FullCodeGenerator::Split(Condition cond, 680 void FullCodeGenerator::Split(Condition cond,
676 Label* if_true, 681 Label* if_true,
677 Label* if_false, 682 Label* if_false,
678 Label* fall_through) { 683 Label* fall_through) {
679 if (if_false == fall_through) { 684 if (if_false == fall_through) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 __ cmp(r1, r0); 1025 __ cmp(r1, r0);
1021 __ b(ne, &next_test); 1026 __ b(ne, &next_test);
1022 __ Drop(1); // Switch value is no longer needed. 1027 __ Drop(1); // Switch value is no longer needed.
1023 __ b(clause->body_target()); 1028 __ b(clause->body_target());
1024 __ bind(&slow_case); 1029 __ bind(&slow_case);
1025 } 1030 }
1026 1031
1027 // Record position before stub call for type feedback. 1032 // Record position before stub call for type feedback.
1028 SetSourcePosition(clause->position()); 1033 SetSourcePosition(clause->position());
1029 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 1034 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
1030 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); 1035 CallIC(ic, clause->CompareId());
1031 patch_site.EmitPatchInfo(); 1036 patch_site.EmitPatchInfo();
1032 1037
1033 Label skip; 1038 Label skip;
1034 __ b(&skip); 1039 __ b(&skip);
1035 PrepareForBailout(clause, TOS_REG); 1040 PrepareForBailout(clause, TOS_REG);
1036 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 1041 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
1037 __ cmp(r0, ip); 1042 __ cmp(r0, ip);
1038 __ b(ne, &next_test); 1043 __ b(ne, &next_test);
1039 __ Drop(1); 1044 __ Drop(1);
1040 __ jmp(clause->body_target()); 1045 __ jmp(clause->body_target());
(...skipping 24 matching lines...) Expand all
1065 VisitStatements(clause->statements()); 1070 VisitStatements(clause->statements());
1066 } 1071 }
1067 1072
1068 __ bind(nested_statement.break_label()); 1073 __ bind(nested_statement.break_label());
1069 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1074 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1070 } 1075 }
1071 1076
1072 1077
1073 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1078 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1074 Comment cmnt(masm_, "[ ForInStatement"); 1079 Comment cmnt(masm_, "[ ForInStatement");
1080 int slot = stmt->ForInFeedbackSlot();
1075 SetStatementPosition(stmt); 1081 SetStatementPosition(stmt);
1076 1082
1077 Label loop, exit; 1083 Label loop, exit;
1078 ForIn loop_statement(this, stmt); 1084 ForIn loop_statement(this, stmt);
1079 increment_loop_depth(); 1085 increment_loop_depth();
1080 1086
1081 // Get the object to enumerate over. If the object is null or undefined, skip 1087 // Get the object to enumerate over. If the object is null or undefined, skip
1082 // over the loop. See ECMA-262 version 5, section 12.6.4. 1088 // over the loop. See ECMA-262 version 5, section 12.6.4.
1083 VisitForAccumulatorValue(stmt->enumerable()); 1089 VisitForAccumulatorValue(stmt->enumerable());
1084 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1090 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 __ jmp(&loop); 1160 __ jmp(&loop);
1155 1161
1156 __ bind(&no_descriptors); 1162 __ bind(&no_descriptors);
1157 __ Drop(1); 1163 __ Drop(1);
1158 __ jmp(&exit); 1164 __ jmp(&exit);
1159 1165
1160 // We got a fixed array in register r0. Iterate through that. 1166 // We got a fixed array in register r0. Iterate through that.
1161 Label non_proxy; 1167 Label non_proxy;
1162 __ bind(&fixed_array); 1168 __ bind(&fixed_array);
1163 1169
1164 Handle<Cell> cell = isolate()->factory()->NewCell( 1170 Handle<Object> feedback = Handle<Object>(
1165 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), 1171 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
1166 isolate())); 1172 isolate());
1167 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); 1173 StoreFeedbackVectorSlot(slot, feedback);
1168 __ Move(r1, cell); 1174 __ Move(r1, FeedbackVector());
1169 __ mov(r2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); 1175 __ mov(r2, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
1170 __ str(r2, FieldMemOperand(r1, Cell::kValueOffset)); 1176 __ str(r2, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(slot)));
1171 1177
1172 __ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check 1178 __ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check
1173 __ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object 1179 __ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
1174 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1180 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1175 __ CompareObjectType(r2, r3, r3, LAST_JS_PROXY_TYPE); 1181 __ CompareObjectType(r2, r3, r3, LAST_JS_PROXY_TYPE);
1176 __ b(gt, &non_proxy); 1182 __ b(gt, &non_proxy);
1177 __ mov(r1, Operand(Smi::FromInt(0))); // Zero indicates proxy 1183 __ mov(r1, Operand(Smi::FromInt(0))); // Zero indicates proxy
1178 __ bind(&non_proxy); 1184 __ bind(&non_proxy);
1179 __ Push(r1, r0); // Smi and array 1185 __ Push(r1, r0); // Smi and array
1180 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset)); 1186 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset));
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 1475
1470 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1476 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
1471 // Record position before possible IC call. 1477 // Record position before possible IC call.
1472 SetSourcePosition(proxy->position()); 1478 SetSourcePosition(proxy->position());
1473 Variable* var = proxy->var(); 1479 Variable* var = proxy->var();
1474 1480
1475 // Three cases: global variables, lookup variables, and all other types of 1481 // Three cases: global variables, lookup variables, and all other types of
1476 // variables. 1482 // variables.
1477 switch (var->location()) { 1483 switch (var->location()) {
1478 case Variable::UNALLOCATED: { 1484 case Variable::UNALLOCATED: {
1479 Comment cmnt(masm_, "Global variable"); 1485 Comment cmnt(masm_, "[ Global variable");
1480 // Use inline caching. Variable name is passed in r2 and the global 1486 // Use inline caching. Variable name is passed in r2 and the global
1481 // object (receiver) in r0. 1487 // object (receiver) in r0.
1482 __ ldr(r0, GlobalObjectOperand()); 1488 __ ldr(r0, GlobalObjectOperand());
1483 __ mov(r2, Operand(var->name())); 1489 __ mov(r2, Operand(var->name()));
1484 CallLoadIC(CONTEXTUAL); 1490 CallLoadIC(CONTEXTUAL);
1485 context()->Plug(r0); 1491 context()->Plug(r0);
1486 break; 1492 break;
1487 } 1493 }
1488 1494
1489 case Variable::PARAMETER: 1495 case Variable::PARAMETER:
1490 case Variable::LOCAL: 1496 case Variable::LOCAL:
1491 case Variable::CONTEXT: { 1497 case Variable::CONTEXT: {
1492 Comment cmnt(masm_, var->IsContextSlot() 1498 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1493 ? "Context variable" 1499 : "[ Stack variable");
1494 : "Stack variable");
1495 if (var->binding_needs_init()) { 1500 if (var->binding_needs_init()) {
1496 // var->scope() may be NULL when the proxy is located in eval code and 1501 // var->scope() may be NULL when the proxy is located in eval code and
1497 // refers to a potential outside binding. Currently those bindings are 1502 // refers to a potential outside binding. Currently those bindings are
1498 // always looked up dynamically, i.e. in that case 1503 // always looked up dynamically, i.e. in that case
1499 // var->location() == LOOKUP. 1504 // var->location() == LOOKUP.
1500 // always holds. 1505 // always holds.
1501 ASSERT(var->scope() != NULL); 1506 ASSERT(var->scope() != NULL);
1502 1507
1503 // Check if the binding really needs an initialization check. The check 1508 // Check if the binding really needs an initialization check. The check
1504 // can be skipped in the following situation: we have a LET or CONST 1509 // can be skipped in the following situation: we have a LET or CONST
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1547 } 1552 }
1548 context()->Plug(r0); 1553 context()->Plug(r0);
1549 break; 1554 break;
1550 } 1555 }
1551 } 1556 }
1552 context()->Plug(var); 1557 context()->Plug(var);
1553 break; 1558 break;
1554 } 1559 }
1555 1560
1556 case Variable::LOOKUP: { 1561 case Variable::LOOKUP: {
1562 Comment cmnt(masm_, "[ Lookup variable");
1557 Label done, slow; 1563 Label done, slow;
1558 // Generate code for loading from variables potentially shadowed 1564 // Generate code for loading from variables potentially shadowed
1559 // by eval-introduced variables. 1565 // by eval-introduced variables.
1560 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); 1566 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done);
1561 __ bind(&slow); 1567 __ bind(&slow);
1562 Comment cmnt(masm_, "Lookup variable");
1563 __ mov(r1, Operand(var->name())); 1568 __ mov(r1, Operand(var->name()));
1564 __ Push(cp, r1); // Context and name. 1569 __ Push(cp, r1); // Context and name.
1565 __ CallRuntime(Runtime::kLoadContextSlot, 2); 1570 __ CallRuntime(Runtime::kLoadContextSlot, 2);
1566 __ bind(&done); 1571 __ bind(&done);
1567 context()->Plug(r0); 1572 context()->Plug(r0);
1568 } 1573 }
1569 } 1574 }
1570 } 1575 }
1571 1576
1572 1577
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 UNREACHABLE(); 1688 UNREACHABLE();
1684 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1689 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1685 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1690 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
1686 // Fall through. 1691 // Fall through.
1687 case ObjectLiteral::Property::COMPUTED: 1692 case ObjectLiteral::Property::COMPUTED:
1688 if (key->value()->IsInternalizedString()) { 1693 if (key->value()->IsInternalizedString()) {
1689 if (property->emit_store()) { 1694 if (property->emit_store()) {
1690 VisitForAccumulatorValue(value); 1695 VisitForAccumulatorValue(value);
1691 __ mov(r2, Operand(key->value())); 1696 __ mov(r2, Operand(key->value()));
1692 __ ldr(r1, MemOperand(sp)); 1697 __ ldr(r1, MemOperand(sp));
1693 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); 1698 CallStoreIC(key->LiteralFeedbackId());
1694 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1699 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1695 } else { 1700 } else {
1696 VisitForEffect(value); 1701 VisitForEffect(value);
1697 } 1702 }
1698 break; 1703 break;
1699 } 1704 }
1700 // Duplicate receiver on stack. 1705 // Duplicate receiver on stack.
1701 __ ldr(r0, MemOperand(sp)); 1706 __ ldr(r0, MemOperand(sp));
1702 __ push(r0); 1707 __ push(r0);
1703 VisitForStackValue(key); 1708 VisitForStackValue(key);
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 2045
2041 Label l_catch, l_try, l_suspend, l_continuation, l_resume; 2046 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
2042 Label l_next, l_call, l_loop; 2047 Label l_next, l_call, l_loop;
2043 // Initial send value is undefined. 2048 // Initial send value is undefined.
2044 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 2049 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2045 __ b(&l_next); 2050 __ b(&l_next);
2046 2051
2047 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2052 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2048 __ bind(&l_catch); 2053 __ bind(&l_catch);
2049 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2054 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2050 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw" 2055 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw"
2051 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2056 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2052 __ Push(r3, r0); // iter, exception 2057 __ Push(r2, r3, r0); // "throw", iter, except
2053 __ jmp(&l_call); 2058 __ jmp(&l_call);
2054 2059
2055 // try { received = %yield result } 2060 // try { received = %yield result }
2056 // Shuffle the received result above a try handler and yield it without 2061 // Shuffle the received result above a try handler and yield it without
2057 // re-boxing. 2062 // re-boxing.
2058 __ bind(&l_try); 2063 __ bind(&l_try);
2059 __ pop(r0); // result 2064 __ pop(r0); // result
2060 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2065 __ PushTryHandler(StackHandler::CATCH, expr->index());
2061 const int handler_size = StackHandlerConstants::kSize; 2066 const int handler_size = StackHandlerConstants::kSize;
2062 __ push(r0); // result 2067 __ push(r0); // result
2063 __ jmp(&l_suspend); 2068 __ jmp(&l_suspend);
2064 __ bind(&l_continuation); 2069 __ bind(&l_continuation);
2065 __ jmp(&l_resume); 2070 __ jmp(&l_resume);
2066 __ bind(&l_suspend); 2071 __ bind(&l_suspend);
2067 const int generator_object_depth = kPointerSize + handler_size; 2072 const int generator_object_depth = kPointerSize + handler_size;
2068 __ ldr(r0, MemOperand(sp, generator_object_depth)); 2073 __ ldr(r0, MemOperand(sp, generator_object_depth));
2069 __ push(r0); // g 2074 __ push(r0); // g
2070 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); 2075 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
2071 __ mov(r1, Operand(Smi::FromInt(l_continuation.pos()))); 2076 __ mov(r1, Operand(Smi::FromInt(l_continuation.pos())));
2072 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); 2077 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset));
2073 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); 2078 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset));
2074 __ mov(r1, cp); 2079 __ mov(r1, cp);
2075 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, 2080 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2,
2076 kLRHasBeenSaved, kDontSaveFPRegs); 2081 kLRHasBeenSaved, kDontSaveFPRegs);
2077 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2082 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2078 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2083 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2079 __ pop(r0); // result 2084 __ pop(r0); // result
2080 EmitReturnSequence(); 2085 EmitReturnSequence();
2081 __ bind(&l_resume); // received in r0 2086 __ bind(&l_resume); // received in r0
2082 __ PopTryHandler(); 2087 __ PopTryHandler();
2083 2088
2084 // receiver = iter; f = 'next'; arg = received; 2089 // receiver = iter; f = 'next'; arg = received;
2085 __ bind(&l_next); 2090 __ bind(&l_next);
2086 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" 2091 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next"
2087 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2092 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2088 __ Push(r3, r0); // iter, received 2093 __ Push(r2, r3, r0); // "next", iter, received
2089 2094
2090 // result = receiver[f](arg); 2095 // result = receiver[f](arg);
2091 __ bind(&l_call); 2096 __ bind(&l_call);
2092 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); 2097 __ ldr(r1, MemOperand(sp, kPointerSize));
2093 CallIC(ic); 2098 __ ldr(r0, MemOperand(sp, 2 * kPointerSize));
2099 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2100 CallIC(ic, TypeFeedbackId::None());
2101 __ mov(r1, r0);
2102 __ str(r1, MemOperand(sp, 2 * kPointerSize));
2103 CallFunctionStub stub(1, CALL_AS_METHOD);
2104 __ CallStub(&stub);
2105
2094 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2106 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2107 __ Drop(1); // The function is still on the stack; drop it.
2095 2108
2096 // if (!result.done) goto l_try; 2109 // if (!result.done) goto l_try;
2097 __ bind(&l_loop); 2110 __ bind(&l_loop);
2098 __ push(r0); // save result 2111 __ push(r0); // save result
2099 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" 2112 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done"
2100 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 2113 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0
2101 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2114 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2102 CallIC(bool_ic); 2115 CallIC(bool_ic);
2103 __ cmp(r0, Operand(0)); 2116 __ cmp(r0, Operand(0));
2104 __ b(eq, &l_try); 2117 __ b(eq, &l_try);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2274 __ mov(r2, Operand(key->value())); 2287 __ mov(r2, Operand(key->value()));
2275 // Call load IC. It has arguments receiver and property name r0 and r2. 2288 // Call load IC. It has arguments receiver and property name r0 and r2.
2276 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2289 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2277 } 2290 }
2278 2291
2279 2292
2280 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2293 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2281 SetSourcePosition(prop->position()); 2294 SetSourcePosition(prop->position());
2282 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 2295 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
2283 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2296 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2284 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2297 CallIC(ic, prop->PropertyFeedbackId());
2285 } 2298 }
2286 2299
2287 2300
2288 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2301 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2289 Token::Value op, 2302 Token::Value op,
2290 OverwriteMode mode, 2303 OverwriteMode mode,
2291 Expression* left_expr, 2304 Expression* left_expr,
2292 Expression* right_expr) { 2305 Expression* right_expr) {
2293 Label done, smi_case, stub_call; 2306 Label done, smi_case, stub_call;
2294 2307
2295 Register scratch1 = r2; 2308 Register scratch1 = r2;
2296 Register scratch2 = r3; 2309 Register scratch2 = r3;
2297 2310
2298 // Get the arguments. 2311 // Get the arguments.
2299 Register left = r1; 2312 Register left = r1;
2300 Register right = r0; 2313 Register right = r0;
2301 __ pop(left); 2314 __ pop(left);
2302 2315
2303 // Perform combined smi check on both operands. 2316 // Perform combined smi check on both operands.
2304 __ orr(scratch1, left, Operand(right)); 2317 __ orr(scratch1, left, Operand(right));
2305 STATIC_ASSERT(kSmiTag == 0); 2318 STATIC_ASSERT(kSmiTag == 0);
2306 JumpPatchSite patch_site(masm_); 2319 JumpPatchSite patch_site(masm_);
2307 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 2320 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2308 2321
2309 __ bind(&stub_call); 2322 __ bind(&stub_call);
2310 BinaryOpICStub stub(op, mode); 2323 BinaryOpICStub stub(op, mode);
2311 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2324 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2312 expr->BinaryOperationFeedbackId());
2313 patch_site.EmitPatchInfo(); 2325 patch_site.EmitPatchInfo();
2314 __ jmp(&done); 2326 __ jmp(&done);
2315 2327
2316 __ bind(&smi_case); 2328 __ bind(&smi_case);
2317 // Smi case. This code works the same way as the smi-smi case in the type 2329 // Smi case. This code works the same way as the smi-smi case in the type
2318 // recording binary operation stub, see 2330 // recording binary operation stub, see
2319 switch (op) { 2331 switch (op) {
2320 case Token::SAR: 2332 case Token::SAR:
2321 __ GetLeastBitsFromSmi(scratch1, right, 5); 2333 __ GetLeastBitsFromSmi(scratch1, right, 5);
2322 __ mov(right, Operand(left, ASR, scratch1)); 2334 __ mov(right, Operand(left, ASR, scratch1));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 context()->Plug(r0); 2391 context()->Plug(r0);
2380 } 2392 }
2381 2393
2382 2394
2383 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 2395 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
2384 Token::Value op, 2396 Token::Value op,
2385 OverwriteMode mode) { 2397 OverwriteMode mode) {
2386 __ pop(r1); 2398 __ pop(r1);
2387 BinaryOpICStub stub(op, mode); 2399 BinaryOpICStub stub(op, mode);
2388 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2400 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2389 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2401 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2390 expr->BinaryOperationFeedbackId());
2391 patch_site.EmitPatchInfo(); 2402 patch_site.EmitPatchInfo();
2392 context()->Plug(r0); 2403 context()->Plug(r0);
2393 } 2404 }
2394 2405
2395 2406
2396 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2407 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2397 // Invalid left-hand sides are rewritten by the parser to have a 'throw 2408 // Invalid left-hand sides are rewritten by the parser to have a 'throw
2398 // ReferenceError' on the left-hand side. 2409 // ReferenceError' on the left-hand side.
2399 if (!expr->IsValidLeftHandSide()) { 2410 if (!expr->IsValidLeftHandSide()) {
2400 VisitForEffect(expr); 2411 VisitForEffect(expr);
(...skipping 17 matching lines...) Expand all
2418 EffectContext context(this); 2429 EffectContext context(this);
2419 EmitVariableAssignment(var, Token::ASSIGN); 2430 EmitVariableAssignment(var, Token::ASSIGN);
2420 break; 2431 break;
2421 } 2432 }
2422 case NAMED_PROPERTY: { 2433 case NAMED_PROPERTY: {
2423 __ push(r0); // Preserve value. 2434 __ push(r0); // Preserve value.
2424 VisitForAccumulatorValue(prop->obj()); 2435 VisitForAccumulatorValue(prop->obj());
2425 __ mov(r1, r0); 2436 __ mov(r1, r0);
2426 __ pop(r0); // Restore value. 2437 __ pop(r0); // Restore value.
2427 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); 2438 __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
2428 CallStoreIC(NOT_CONTEXTUAL); 2439 CallStoreIC();
2429 break; 2440 break;
2430 } 2441 }
2431 case KEYED_PROPERTY: { 2442 case KEYED_PROPERTY: {
2432 __ push(r0); // Preserve value. 2443 __ push(r0); // Preserve value.
2433 VisitForStackValue(prop->obj()); 2444 VisitForStackValue(prop->obj());
2434 VisitForAccumulatorValue(prop->key()); 2445 VisitForAccumulatorValue(prop->key());
2435 __ mov(r1, r0); 2446 __ mov(r1, r0);
2436 __ Pop(r0, r2); // r0 = restored value. 2447 __ Pop(r0, r2); // r0 = restored value.
2437 Handle<Code> ic = is_classic_mode() 2448 Handle<Code> ic = is_classic_mode()
2438 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2449 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2439 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2450 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2440 CallIC(ic); 2451 CallIC(ic);
2441 break; 2452 break;
2442 } 2453 }
2443 } 2454 }
2444 context()->Plug(r0); 2455 context()->Plug(r0);
2445 } 2456 }
2446 2457
2447 2458
2459 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2460 Variable* var, MemOperand location) {
2461 __ str(result_register(), location);
2462 if (var->IsContextSlot()) {
2463 // RecordWrite may destroy all its register arguments.
2464 __ mov(r3, result_register());
2465 int offset = Context::SlotOffset(var->index());
2466 __ RecordWriteContextSlot(
2467 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
2468 }
2469 }
2470
2471
2472 void FullCodeGenerator::EmitCallStoreContextSlot(
2473 Handle<String> name, LanguageMode mode) {
2474 __ push(r0); // Value.
2475 __ mov(r1, Operand(name));
2476 __ mov(r0, Operand(Smi::FromInt(mode)));
2477 __ Push(cp, r1, r0); // Context, name, strict mode.
2478 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2479 }
2480
2481
2448 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2482 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2449 Token::Value op) { 2483 Token::Value op) {
2450 if (var->IsUnallocated()) { 2484 if (var->IsUnallocated()) {
2451 // Global var, const, or let. 2485 // Global var, const, or let.
2452 __ mov(r2, Operand(var->name())); 2486 __ mov(r2, Operand(var->name()));
2453 __ ldr(r1, GlobalObjectOperand()); 2487 __ ldr(r1, GlobalObjectOperand());
2454 CallStoreIC(CONTEXTUAL); 2488 CallStoreIC();
2489
2455 } else if (op == Token::INIT_CONST) { 2490 } else if (op == Token::INIT_CONST) {
2456 // Const initializers need a write barrier. 2491 // Const initializers need a write barrier.
2457 ASSERT(!var->IsParameter()); // No const parameters. 2492 ASSERT(!var->IsParameter()); // No const parameters.
2458 if (var->IsStackLocal()) { 2493 if (var->IsLookupSlot()) {
2459 __ ldr(r1, StackOperand(var));
2460 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
2461 __ str(result_register(), StackOperand(var), eq);
2462 } else {
2463 ASSERT(var->IsContextSlot() || var->IsLookupSlot());
2464 // Like var declarations, const declarations are hoisted to function
2465 // scope. However, unlike var initializers, const initializers are
2466 // able to drill a hole to that function context, even from inside a
2467 // 'with' context. We thus bypass the normal static scope lookup for
2468 // var->IsContextSlot().
2469 __ push(r0); 2494 __ push(r0);
2470 __ mov(r0, Operand(var->name())); 2495 __ mov(r0, Operand(var->name()));
2471 __ Push(cp, r0); // Context and name. 2496 __ Push(cp, r0); // Context and name.
2472 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 2497 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
2498 } else {
2499 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2500 Label skip;
2501 MemOperand location = VarOperand(var, r1);
2502 __ ldr(r2, location);
2503 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
2504 __ b(ne, &skip);
2505 EmitStoreToStackLocalOrContextSlot(var, location);
2506 __ bind(&skip);
2473 } 2507 }
2474 2508
2475 } else if (var->mode() == LET && op != Token::INIT_LET) { 2509 } else if (var->mode() == LET && op != Token::INIT_LET) {
2476 // Non-initializing assignment to let variable needs a write barrier. 2510 // Non-initializing assignment to let variable needs a write barrier.
2477 if (var->IsLookupSlot()) { 2511 if (var->IsLookupSlot()) {
2478 __ push(r0); // Value. 2512 EmitCallStoreContextSlot(var->name(), language_mode());
2479 __ mov(r1, Operand(var->name()));
2480 __ mov(r0, Operand(Smi::FromInt(language_mode())));
2481 __ Push(cp, r1, r0); // Context, name, strict mode.
2482 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2483 } else { 2513 } else {
2484 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2514 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2485 Label assign; 2515 Label assign;
2486 MemOperand location = VarOperand(var, r1); 2516 MemOperand location = VarOperand(var, r1);
2487 __ ldr(r3, location); 2517 __ ldr(r3, location);
2488 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 2518 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
2489 __ b(ne, &assign); 2519 __ b(ne, &assign);
2490 __ mov(r3, Operand(var->name())); 2520 __ mov(r3, Operand(var->name()));
2491 __ push(r3); 2521 __ push(r3);
2492 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2522 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2493 // Perform the assignment. 2523 // Perform the assignment.
2494 __ bind(&assign); 2524 __ bind(&assign);
2495 __ str(result_register(), location); 2525 EmitStoreToStackLocalOrContextSlot(var, location);
2496 if (var->IsContextSlot()) {
2497 // RecordWrite may destroy all its register arguments.
2498 __ mov(r3, result_register());
2499 int offset = Context::SlotOffset(var->index());
2500 __ RecordWriteContextSlot(
2501 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
2502 }
2503 } 2526 }
2504 2527
2505 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { 2528 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) {
2506 // Assignment to var or initializing assignment to let/const 2529 // Assignment to var or initializing assignment to let/const
2507 // in harmony mode. 2530 // in harmony mode.
2508 if (var->IsStackAllocated() || var->IsContextSlot()) { 2531 if (var->IsLookupSlot()) {
2532 EmitCallStoreContextSlot(var->name(), language_mode());
2533 } else {
2534 ASSERT((var->IsStackAllocated() || var->IsContextSlot()));
2509 MemOperand location = VarOperand(var, r1); 2535 MemOperand location = VarOperand(var, r1);
2510 if (generate_debug_code_ && op == Token::INIT_LET) { 2536 if (generate_debug_code_ && op == Token::INIT_LET) {
2511 // Check for an uninitialized let binding. 2537 // Check for an uninitialized let binding.
2512 __ ldr(r2, location); 2538 __ ldr(r2, location);
2513 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); 2539 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
2514 __ Check(eq, kLetBindingReInitialization); 2540 __ Check(eq, kLetBindingReInitialization);
2515 } 2541 }
2516 // Perform the assignment. 2542 EmitStoreToStackLocalOrContextSlot(var, location);
2517 __ str(r0, location);
2518 if (var->IsContextSlot()) {
2519 __ mov(r3, r0);
2520 int offset = Context::SlotOffset(var->index());
2521 __ RecordWriteContextSlot(
2522 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
2523 }
2524 } else {
2525 ASSERT(var->IsLookupSlot());
2526 __ push(r0); // Value.
2527 __ mov(r1, Operand(var->name()));
2528 __ mov(r0, Operand(Smi::FromInt(language_mode())));
2529 __ Push(cp, r1, r0); // Context, name, strict mode.
2530 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2531 } 2543 }
2532 } 2544 }
2533 // Non-initializing assignments to consts are ignored. 2545 // Non-initializing assignments to consts are ignored.
2534 } 2546 }
2535 2547
2536 2548
2537 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2549 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2538 // Assignment to a property, using a named store IC. 2550 // Assignment to a property, using a named store IC.
2539 Property* prop = expr->target()->AsProperty(); 2551 Property* prop = expr->target()->AsProperty();
2540 ASSERT(prop != NULL); 2552 ASSERT(prop != NULL);
2541 ASSERT(prop->key()->AsLiteral() != NULL); 2553 ASSERT(prop->key()->AsLiteral() != NULL);
2542 2554
2543 // Record source code position before IC call. 2555 // Record source code position before IC call.
2544 SetSourcePosition(expr->position()); 2556 SetSourcePosition(expr->position());
2545 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); 2557 __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
2546 __ pop(r1); 2558 __ pop(r1);
2547 2559
2548 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2560 CallStoreIC(expr->AssignmentFeedbackId());
2549 2561
2550 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2562 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2551 context()->Plug(r0); 2563 context()->Plug(r0);
2552 } 2564 }
2553 2565
2554 2566
2555 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2567 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2556 // Assignment to a property, using a keyed store IC. 2568 // Assignment to a property, using a keyed store IC.
2557 2569
2558 // Record source code position before IC call. 2570 // Record source code position before IC call.
2559 SetSourcePosition(expr->position()); 2571 SetSourcePosition(expr->position());
2560 __ Pop(r2, r1); // r1 = key. 2572 __ Pop(r2, r1); // r1 = key.
2561 2573
2562 Handle<Code> ic = is_classic_mode() 2574 Handle<Code> ic = is_classic_mode()
2563 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2575 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2564 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2576 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2565 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2577 CallIC(ic, expr->AssignmentFeedbackId());
2566 2578
2567 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2579 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2568 context()->Plug(r0); 2580 context()->Plug(r0);
2569 } 2581 }
2570 2582
2571 2583
2572 void FullCodeGenerator::VisitProperty(Property* expr) { 2584 void FullCodeGenerator::VisitProperty(Property* expr) {
2573 Comment cmnt(masm_, "[ Property"); 2585 Comment cmnt(masm_, "[ Property");
2574 Expression* key = expr->key(); 2586 Expression* key = expr->key();
2575 2587
2576 if (key->IsPropertyName()) { 2588 if (key->IsPropertyName()) {
2577 VisitForAccumulatorValue(expr->obj()); 2589 VisitForAccumulatorValue(expr->obj());
2578 EmitNamedPropertyLoad(expr); 2590 EmitNamedPropertyLoad(expr);
2579 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2591 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2580 context()->Plug(r0); 2592 context()->Plug(r0);
2581 } else { 2593 } else {
2582 VisitForStackValue(expr->obj()); 2594 VisitForStackValue(expr->obj());
2583 VisitForAccumulatorValue(expr->key()); 2595 VisitForAccumulatorValue(expr->key());
2584 __ pop(r1); 2596 __ pop(r1);
2585 EmitKeyedPropertyLoad(expr); 2597 EmitKeyedPropertyLoad(expr);
2586 context()->Plug(r0); 2598 context()->Plug(r0);
2587 } 2599 }
2588 } 2600 }
2589 2601
2590 2602
2591 void FullCodeGenerator::CallIC(Handle<Code> code, 2603 void FullCodeGenerator::CallIC(Handle<Code> code,
2592 ContextualMode mode,
2593 TypeFeedbackId ast_id) { 2604 TypeFeedbackId ast_id) {
2594 ic_total_count_++; 2605 ic_total_count_++;
2595 // All calls must have a predictable size in full-codegen code to ensure that 2606 // All calls must have a predictable size in full-codegen code to ensure that
2596 // the debugger can patch them correctly. 2607 // the debugger can patch them correctly.
2597 ASSERT(mode != CONTEXTUAL || ast_id.IsNone());
2598 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, 2608 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al,
2599 NEVER_INLINE_TARGET_ADDRESS); 2609 NEVER_INLINE_TARGET_ADDRESS);
2600 } 2610 }
2601 2611
2602 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2612
2603 Handle<Object> name, 2613 // Code common for calls using the IC.
2604 ContextualMode mode) { 2614 void FullCodeGenerator::EmitCallWithIC(Call* expr) {
2605 // Code common for calls using the IC. 2615 Expression* callee = expr->expression();
2606 ZoneList<Expression*>* args = expr->arguments(); 2616 ZoneList<Expression*>* args = expr->arguments();
2607 int arg_count = args->length(); 2617 int arg_count = args->length();
2618
2619 CallFunctionFlags flags;
2620 // Get the target function.
2621 if (callee->IsVariableProxy()) {
2622 { StackValueContext context(this);
2623 EmitVariableLoad(callee->AsVariableProxy());
2624 PrepareForBailout(callee, NO_REGISTERS);
2625 }
2626 // Push undefined as receiver. This is patched in the method prologue if it
2627 // is a classic mode method.
2628 __ Push(isolate()->factory()->undefined_value());
2629 flags = NO_CALL_FUNCTION_FLAGS;
2630 } else {
2631 // Load the function from the receiver.
2632 ASSERT(callee->IsProperty());
2633 __ ldr(r0, MemOperand(sp, 0));
2634 EmitNamedPropertyLoad(callee->AsProperty());
2635 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2636 // Push the target function under the receiver.
2637 __ ldr(ip, MemOperand(sp, 0));
2638 __ push(ip);
2639 __ str(r0, MemOperand(sp, kPointerSize));
2640 flags = CALL_AS_METHOD;
2641 }
2642
2643 // Load the arguments.
2608 { PreservePositionScope scope(masm()->positions_recorder()); 2644 { PreservePositionScope scope(masm()->positions_recorder());
2609 for (int i = 0; i < arg_count; i++) { 2645 for (int i = 0; i < arg_count; i++) {
2610 VisitForStackValue(args->at(i)); 2646 VisitForStackValue(args->at(i));
2611 } 2647 }
2612 __ mov(r2, Operand(name));
2613 } 2648 }
2649
2614 // Record source position for debugger. 2650 // Record source position for debugger.
2615 SetSourcePosition(expr->position()); 2651 SetSourcePosition(expr->position());
2616 // Call the IC initialization code. 2652 CallFunctionStub stub(arg_count, flags);
2617 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); 2653 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2618 TypeFeedbackId ast_id = mode == CONTEXTUAL 2654 __ CallStub(&stub);
2619 ? TypeFeedbackId::None() 2655
2620 : expr->CallFeedbackId();
2621 CallIC(ic, mode, ast_id);
2622 RecordJSReturnSite(expr); 2656 RecordJSReturnSite(expr);
2657
2623 // Restore context register. 2658 // Restore context register.
2624 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2659 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2625 context()->Plug(r0); 2660
2661 context()->DropAndPlug(1, r0);
2626 } 2662 }
2627 2663
2628 2664
2665 // Code common for calls using the IC.
2629 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2666 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2630 Expression* key) { 2667 Expression* key) {
2631 // Load the key. 2668 // Load the key.
2632 VisitForAccumulatorValue(key); 2669 VisitForAccumulatorValue(key);
2633 2670
2634 // Swap the name of the function and the receiver on the stack to follow 2671 Expression* callee = expr->expression();
2635 // the calling convention for call ICs.
2636 __ pop(r1);
2637 __ push(r0);
2638 __ push(r1);
2639
2640 // Code common for calls using the IC.
2641 ZoneList<Expression*>* args = expr->arguments(); 2672 ZoneList<Expression*>* args = expr->arguments();
2642 int arg_count = args->length(); 2673 int arg_count = args->length();
2674
2675 // Load the function from the receiver.
2676 ASSERT(callee->IsProperty());
2677 __ ldr(r1, MemOperand(sp, 0));
2678 EmitKeyedPropertyLoad(callee->AsProperty());
2679 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2680
2681 // Push the target function under the receiver.
2682 __ ldr(ip, MemOperand(sp, 0));
2683 __ push(ip);
2684 __ str(r0, MemOperand(sp, kPointerSize));
2685
2643 { PreservePositionScope scope(masm()->positions_recorder()); 2686 { PreservePositionScope scope(masm()->positions_recorder());
2644 for (int i = 0; i < arg_count; i++) { 2687 for (int i = 0; i < arg_count; i++) {
2645 VisitForStackValue(args->at(i)); 2688 VisitForStackValue(args->at(i));
2646 } 2689 }
2647 } 2690 }
2691
2648 // Record source position for debugger. 2692 // Record source position for debugger.
2649 SetSourcePosition(expr->position()); 2693 SetSourcePosition(expr->position());
2650 // Call the IC initialization code. 2694 CallFunctionStub stub(arg_count, CALL_AS_METHOD);
2651 Handle<Code> ic = 2695 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2652 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); 2696 __ CallStub(&stub);
2653 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. 2697
2654 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId());
2655 RecordJSReturnSite(expr); 2698 RecordJSReturnSite(expr);
2656 // Restore context register. 2699 // Restore context register.
2657 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2700 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2658 context()->DropAndPlug(1, r0); // Drop the key still on the stack. 2701
2702 context()->DropAndPlug(1, r0);
2659 } 2703 }
2660 2704
2661 2705
2662 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2706 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2663 // Code common for calls using the call stub. 2707 // Code common for calls using the call stub.
2664 ZoneList<Expression*>* args = expr->arguments(); 2708 ZoneList<Expression*>* args = expr->arguments();
2665 int arg_count = args->length(); 2709 int arg_count = args->length();
2666 { PreservePositionScope scope(masm()->positions_recorder()); 2710 { PreservePositionScope scope(masm()->positions_recorder());
2667 for (int i = 0; i < arg_count; i++) { 2711 for (int i = 0; i < arg_count; i++) {
2668 VisitForStackValue(args->at(i)); 2712 VisitForStackValue(args->at(i));
2669 } 2713 }
2670 } 2714 }
2671 // Record source position for debugger. 2715 // Record source position for debugger.
2672 SetSourcePosition(expr->position()); 2716 SetSourcePosition(expr->position());
2673 2717
2674 Handle<Object> uninitialized = 2718 Handle<Object> uninitialized =
2675 TypeFeedbackCells::UninitializedSentinel(isolate()); 2719 TypeFeedbackInfo::UninitializedSentinel(isolate());
2676 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2720 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
2677 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); 2721 __ Move(r2, FeedbackVector());
2678 __ mov(r2, Operand(cell)); 2722 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
2679 2723
2680 // Record call targets in unoptimized code. 2724 // Record call targets in unoptimized code.
2681 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); 2725 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2682 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2726 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2683 __ CallStub(&stub, expr->CallFeedbackId()); 2727 __ CallStub(&stub);
2684 RecordJSReturnSite(expr); 2728 RecordJSReturnSite(expr);
2685 // Restore context register. 2729 // Restore context register.
2686 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2730 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2687 context()->DropAndPlug(1, r0); 2731 context()->DropAndPlug(1, r0);
2688 } 2732 }
2689 2733
2690 2734
2691 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2735 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2692 // r4: copy of the first argument or undefined if it doesn't exist. 2736 // r4: copy of the first argument or undefined if it doesn't exist.
2693 if (arg_count > 0) { 2737 if (arg_count > 0) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2756 // Record source position for debugger. 2800 // Record source position for debugger.
2757 SetSourcePosition(expr->position()); 2801 SetSourcePosition(expr->position());
2758 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); 2802 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
2759 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2803 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2760 __ CallStub(&stub); 2804 __ CallStub(&stub);
2761 RecordJSReturnSite(expr); 2805 RecordJSReturnSite(expr);
2762 // Restore context register. 2806 // Restore context register.
2763 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2807 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2764 context()->DropAndPlug(1, r0); 2808 context()->DropAndPlug(1, r0);
2765 } else if (call_type == Call::GLOBAL_CALL) { 2809 } else if (call_type == Call::GLOBAL_CALL) {
2766 // Push global object as receiver for the call IC. 2810 EmitCallWithIC(expr);
2767 __ ldr(r0, GlobalObjectOperand()); 2811
2768 __ push(r0);
2769 VariableProxy* proxy = callee->AsVariableProxy();
2770 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL);
2771 } else if (call_type == Call::LOOKUP_SLOT_CALL) { 2812 } else if (call_type == Call::LOOKUP_SLOT_CALL) {
2772 // Call to a lookup slot (dynamically introduced variable). 2813 // Call to a lookup slot (dynamically introduced variable).
2773 VariableProxy* proxy = callee->AsVariableProxy(); 2814 VariableProxy* proxy = callee->AsVariableProxy();
2774 Label slow, done; 2815 Label slow, done;
2775 2816
2776 { PreservePositionScope scope(masm()->positions_recorder()); 2817 { PreservePositionScope scope(masm()->positions_recorder());
2777 // Generate code for loading from variables potentially shadowed 2818 // Generate code for loading from variables potentially shadowed
2778 // by eval-introduced variables. 2819 // by eval-introduced variables.
2779 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2820 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2780 } 2821 }
(...skipping 25 matching lines...) Expand all
2806 2847
2807 // The receiver is either the global receiver or an object found 2848 // The receiver is either the global receiver or an object found
2808 // by LoadContextSlot. 2849 // by LoadContextSlot.
2809 EmitCallWithStub(expr); 2850 EmitCallWithStub(expr);
2810 } else if (call_type == Call::PROPERTY_CALL) { 2851 } else if (call_type == Call::PROPERTY_CALL) {
2811 Property* property = callee->AsProperty(); 2852 Property* property = callee->AsProperty();
2812 { PreservePositionScope scope(masm()->positions_recorder()); 2853 { PreservePositionScope scope(masm()->positions_recorder());
2813 VisitForStackValue(property->obj()); 2854 VisitForStackValue(property->obj());
2814 } 2855 }
2815 if (property->key()->IsPropertyName()) { 2856 if (property->key()->IsPropertyName()) {
2816 EmitCallWithIC(expr, 2857 EmitCallWithIC(expr);
2817 property->key()->AsLiteral()->value(),
2818 NOT_CONTEXTUAL);
2819 } else { 2858 } else {
2820 EmitKeyedCallWithIC(expr, property->key()); 2859 EmitKeyedCallWithIC(expr, property->key());
2821 } 2860 }
2822 } else { 2861 } else {
2823 ASSERT(call_type == Call::OTHER_CALL); 2862 ASSERT(call_type == Call::OTHER_CALL);
2824 // Call to an arbitrary expression not handled specially above. 2863 // Call to an arbitrary expression not handled specially above.
2825 { PreservePositionScope scope(masm()->positions_recorder()); 2864 { PreservePositionScope scope(masm()->positions_recorder());
2826 VisitForStackValue(callee); 2865 VisitForStackValue(callee);
2827 } 2866 }
2828 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2867 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
(...skipping 30 matching lines...) Expand all
2859 // Call the construct call builtin that handles allocation and 2898 // Call the construct call builtin that handles allocation and
2860 // constructor invocation. 2899 // constructor invocation.
2861 SetSourcePosition(expr->position()); 2900 SetSourcePosition(expr->position());
2862 2901
2863 // Load function and argument count into r1 and r0. 2902 // Load function and argument count into r1 and r0.
2864 __ mov(r0, Operand(arg_count)); 2903 __ mov(r0, Operand(arg_count));
2865 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2904 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2866 2905
2867 // Record call targets in unoptimized code. 2906 // Record call targets in unoptimized code.
2868 Handle<Object> uninitialized = 2907 Handle<Object> uninitialized =
2869 TypeFeedbackCells::UninitializedSentinel(isolate()); 2908 TypeFeedbackInfo::UninitializedSentinel(isolate());
2870 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2909 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
2871 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); 2910 __ Move(r2, FeedbackVector());
2872 __ mov(r2, Operand(cell)); 2911 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
2873 2912
2874 CallConstructStub stub(RECORD_CALL_TARGET); 2913 CallConstructStub stub(RECORD_CALL_TARGET);
2875 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2914 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2876 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2915 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2877 context()->Plug(r0); 2916 context()->Plug(r0);
2878 } 2917 }
2879 2918
2880 2919
2881 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2920 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2882 ZoneList<Expression*>* args = expr->arguments(); 2921 ZoneList<Expression*>* args = expr->arguments();
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
3449 Register index = r1; 3488 Register index = r1;
3450 Register value = r2; 3489 Register value = r2;
3451 3490
3452 VisitForStackValue(args->at(1)); // index 3491 VisitForStackValue(args->at(1)); // index
3453 VisitForStackValue(args->at(2)); // value 3492 VisitForStackValue(args->at(2)); // value
3454 VisitForAccumulatorValue(args->at(0)); // string 3493 VisitForAccumulatorValue(args->at(0)); // string
3455 __ Pop(index, value); 3494 __ Pop(index, value);
3456 3495
3457 if (FLAG_debug_code) { 3496 if (FLAG_debug_code) {
3458 __ SmiTst(value); 3497 __ SmiTst(value);
3459 __ ThrowIf(ne, kNonSmiValue); 3498 __ Check(eq, kNonSmiValue);
3460 __ SmiTst(index); 3499 __ SmiTst(index);
3461 __ ThrowIf(ne, kNonSmiIndex); 3500 __ Check(eq, kNonSmiIndex);
3462 __ SmiUntag(index, index); 3501 __ SmiUntag(index, index);
3463 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3502 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3464 __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); 3503 __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
3465 __ SmiTag(index, index); 3504 __ SmiTag(index, index);
3466 } 3505 }
3467 3506
3468 __ SmiUntag(value, value); 3507 __ SmiUntag(value, value);
3469 __ add(ip, 3508 __ add(ip,
3470 string, 3509 string,
3471 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3510 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
(...skipping 10 matching lines...) Expand all
3482 Register index = r1; 3521 Register index = r1;
3483 Register value = r2; 3522 Register value = r2;
3484 3523
3485 VisitForStackValue(args->at(1)); // index 3524 VisitForStackValue(args->at(1)); // index
3486 VisitForStackValue(args->at(2)); // value 3525 VisitForStackValue(args->at(2)); // value
3487 VisitForAccumulatorValue(args->at(0)); // string 3526 VisitForAccumulatorValue(args->at(0)); // string
3488 __ Pop(index, value); 3527 __ Pop(index, value);
3489 3528
3490 if (FLAG_debug_code) { 3529 if (FLAG_debug_code) {
3491 __ SmiTst(value); 3530 __ SmiTst(value);
3492 __ ThrowIf(ne, kNonSmiValue); 3531 __ Check(eq, kNonSmiValue);
3493 __ SmiTst(index); 3532 __ SmiTst(index);
3494 __ ThrowIf(ne, kNonSmiIndex); 3533 __ Check(eq, kNonSmiIndex);
3495 __ SmiUntag(index, index); 3534 __ SmiUntag(index, index);
3496 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3535 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3497 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3536 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
3498 __ SmiTag(index, index); 3537 __ SmiTag(index, index);
3499 } 3538 }
3500 3539
3501 __ SmiUntag(value, value); 3540 __ SmiUntag(value, value);
3502 __ add(ip, 3541 __ add(ip,
3503 string, 3542 string,
3504 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 3543 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
3667 generator.GenerateSlow(masm_, call_helper); 3706 generator.GenerateSlow(masm_, call_helper);
3668 3707
3669 __ bind(&done); 3708 __ bind(&done);
3670 context()->Plug(result); 3709 context()->Plug(result);
3671 } 3710 }
3672 3711
3673 3712
3674 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { 3713 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
3675 ZoneList<Expression*>* args = expr->arguments(); 3714 ZoneList<Expression*>* args = expr->arguments();
3676 ASSERT_EQ(2, args->length()); 3715 ASSERT_EQ(2, args->length());
3716 VisitForStackValue(args->at(0));
3717 VisitForAccumulatorValue(args->at(1));
3677 3718
3678 if (FLAG_new_string_add) { 3719 __ pop(r1);
3679 VisitForStackValue(args->at(0)); 3720 StringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED);
3680 VisitForAccumulatorValue(args->at(1)); 3721 __ CallStub(&stub);
3681
3682 __ pop(r1);
3683 NewStringAddStub stub(STRING_ADD_CHECK_BOTH, NOT_TENURED);
3684 __ CallStub(&stub);
3685 } else {
3686 VisitForStackValue(args->at(0));
3687 VisitForStackValue(args->at(1));
3688
3689 StringAddStub stub(STRING_ADD_CHECK_BOTH);
3690 __ CallStub(&stub);
3691 }
3692 context()->Plug(r0); 3722 context()->Plug(r0);
3693 } 3723 }
3694 3724
3695 3725
3696 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { 3726 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
3697 ZoneList<Expression*>* args = expr->arguments(); 3727 ZoneList<Expression*>* args = expr->arguments();
3698 ASSERT_EQ(2, args->length()); 3728 ASSERT_EQ(2, args->length());
3699 VisitForStackValue(args->at(0)); 3729 VisitForStackValue(args->at(0));
3700 VisitForStackValue(args->at(1)); 3730 VisitForStackValue(args->at(1));
3701 3731
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3756 context()->Plug(r0); 3786 context()->Plug(r0);
3757 } 3787 }
3758 3788
3759 3789
3760 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { 3790 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
3761 RegExpConstructResultStub stub; 3791 RegExpConstructResultStub stub;
3762 ZoneList<Expression*>* args = expr->arguments(); 3792 ZoneList<Expression*>* args = expr->arguments();
3763 ASSERT(args->length() == 3); 3793 ASSERT(args->length() == 3);
3764 VisitForStackValue(args->at(0)); 3794 VisitForStackValue(args->at(0));
3765 VisitForStackValue(args->at(1)); 3795 VisitForStackValue(args->at(1));
3766 VisitForStackValue(args->at(2)); 3796 VisitForAccumulatorValue(args->at(2));
3797 __ pop(r1);
3798 __ pop(r2);
3767 __ CallStub(&stub); 3799 __ CallStub(&stub);
3768 context()->Plug(r0); 3800 context()->Plug(r0);
3769 } 3801 }
3770 3802
3771 3803
3772 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { 3804 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
3773 ZoneList<Expression*>* args = expr->arguments(); 3805 ZoneList<Expression*>* args = expr->arguments();
3774 ASSERT_EQ(2, args->length()); 3806 ASSERT_EQ(2, args->length());
3775 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3807 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3776 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value(); 3808 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value();
(...skipping 12 matching lines...) Expand all
3789 Register key = r0; 3821 Register key = r0;
3790 Register cache = r1; 3822 Register cache = r1;
3791 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 3823 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
3792 __ ldr(cache, FieldMemOperand(cache, GlobalObject::kNativeContextOffset)); 3824 __ ldr(cache, FieldMemOperand(cache, GlobalObject::kNativeContextOffset));
3793 __ ldr(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); 3825 __ ldr(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX));
3794 __ ldr(cache, 3826 __ ldr(cache,
3795 FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); 3827 FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id)));
3796 3828
3797 3829
3798 Label done, not_found; 3830 Label done, not_found;
3799 // tmp now holds finger offset as a smi.
3800 __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset)); 3831 __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset));
3801 // r2 now holds finger offset as a smi. 3832 // r2 now holds finger offset as a smi.
3802 __ add(r3, cache, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 3833 __ add(r3, cache, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3803 // r3 now points to the start of fixed array elements. 3834 // r3 now points to the start of fixed array elements.
3804 __ ldr(r2, MemOperand::PointerAddressFromSmiKey(r3, r2, PreIndex)); 3835 __ ldr(r2, MemOperand::PointerAddressFromSmiKey(r3, r2, PreIndex));
3805 // Note side effect of PreIndex: r3 now points to the key of the pair. 3836 // Note side effect of PreIndex: r3 now points to the key of the pair.
3806 __ cmp(key, r2); 3837 __ cmp(key, r2);
3807 __ b(ne, &not_found); 3838 __ b(ne, &not_found);
3808 3839
3809 __ ldr(r0, MemOperand(r3, kPointerSize)); 3840 __ ldr(r0, MemOperand(r3, kPointerSize));
3810 __ b(&done); 3841 __ b(&done);
3811 3842
3812 __ bind(&not_found); 3843 __ bind(&not_found);
3813 // Call runtime to perform the lookup. 3844 // Call runtime to perform the lookup.
3814 __ Push(cache, key); 3845 __ Push(cache, key);
3815 __ CallRuntime(Runtime::kGetFromCache, 2); 3846 __ CallRuntime(Runtime::kGetFromCache, 2);
3816 3847
3817 __ bind(&done); 3848 __ bind(&done);
3818 context()->Plug(r0); 3849 context()->Plug(r0);
3819 } 3850 }
3820 3851
3821 3852
3822 void FullCodeGenerator::EmitIsRegExpEquivalent(CallRuntime* expr) {
3823 ZoneList<Expression*>* args = expr->arguments();
3824 ASSERT_EQ(2, args->length());
3825
3826 Register right = r0;
3827 Register left = r1;
3828 Register tmp = r2;
3829 Register tmp2 = r3;
3830
3831 VisitForStackValue(args->at(0));
3832 VisitForAccumulatorValue(args->at(1));
3833 __ pop(left);
3834
3835 Label done, fail, ok;
3836 __ cmp(left, Operand(right));
3837 __ b(eq, &ok);
3838 // Fail if either is a non-HeapObject.
3839 __ and_(tmp, left, Operand(right));
3840 __ JumpIfSmi(tmp, &fail);
3841 __ ldr(tmp, FieldMemOperand(left, HeapObject::kMapOffset));
3842 __ ldrb(tmp2, FieldMemOperand(tmp, Map::kInstanceTypeOffset));
3843 __ cmp(tmp2, Operand(JS_REGEXP_TYPE));
3844 __ b(ne, &fail);
3845 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
3846 __ cmp(tmp, Operand(tmp2));
3847 __ b(ne, &fail);
3848 __ ldr(tmp, FieldMemOperand(left, JSRegExp::kDataOffset));
3849 __ ldr(tmp2, FieldMemOperand(right, JSRegExp::kDataOffset));
3850 __ cmp(tmp, tmp2);
3851 __ b(eq, &ok);
3852 __ bind(&fail);
3853 __ LoadRoot(r0, Heap::kFalseValueRootIndex);
3854 __ jmp(&done);
3855 __ bind(&ok);
3856 __ LoadRoot(r0, Heap::kTrueValueRootIndex);
3857 __ bind(&done);
3858
3859 context()->Plug(r0);
3860 }
3861
3862
3863 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3853 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3864 ZoneList<Expression*>* args = expr->arguments(); 3854 ZoneList<Expression*>* args = expr->arguments();
3865 VisitForAccumulatorValue(args->at(0)); 3855 VisitForAccumulatorValue(args->at(0));
3866 3856
3867 Label materialize_true, materialize_false; 3857 Label materialize_true, materialize_false;
3868 Label* if_true = NULL; 3858 Label* if_true = NULL;
3869 Label* if_false = NULL; 3859 Label* if_false = NULL;
3870 Label* fall_through = NULL; 3860 Label* fall_through = NULL;
3871 context()->PrepareTest(&materialize_true, &materialize_false, 3861 context()->PrepareTest(&materialize_true, &materialize_false,
3872 &if_true, &if_false, &fall_through); 3862 &if_true, &if_false, &fall_through);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
4132 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 4122 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
4133 Handle<String> name = expr->name(); 4123 Handle<String> name = expr->name();
4134 if (name->length() > 0 && name->Get(0) == '_') { 4124 if (name->length() > 0 && name->Get(0) == '_') {
4135 Comment cmnt(masm_, "[ InlineRuntimeCall"); 4125 Comment cmnt(masm_, "[ InlineRuntimeCall");
4136 EmitInlineRuntimeCall(expr); 4126 EmitInlineRuntimeCall(expr);
4137 return; 4127 return;
4138 } 4128 }
4139 4129
4140 Comment cmnt(masm_, "[ CallRuntime"); 4130 Comment cmnt(masm_, "[ CallRuntime");
4141 ZoneList<Expression*>* args = expr->arguments(); 4131 ZoneList<Expression*>* args = expr->arguments();
4132 int arg_count = args->length();
4142 4133
4143 if (expr->is_jsruntime()) { 4134 if (expr->is_jsruntime()) {
4144 // Prepare for calling JS runtime function. 4135 // Push the builtins object as the receiver.
4145 __ ldr(r0, GlobalObjectOperand()); 4136 __ ldr(r0, GlobalObjectOperand());
4146 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); 4137 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset));
4147 __ push(r0); 4138 __ push(r0);
4148 }
4149 4139
4150 // Push the arguments ("left-to-right"). 4140 // Load the function from the receiver.
4151 int arg_count = args->length(); 4141 __ mov(r2, Operand(expr->name()));
4152 for (int i = 0; i < arg_count; i++) { 4142 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
4153 VisitForStackValue(args->at(i));
4154 }
4155 4143
4156 if (expr->is_jsruntime()) { 4144 // Push the target function under the receiver.
4157 // Call the JS runtime function. 4145 __ ldr(ip, MemOperand(sp, 0));
4158 __ mov(r2, Operand(expr->name())); 4146 __ push(ip);
4159 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arg_count); 4147 __ str(r0, MemOperand(sp, kPointerSize));
4160 CallIC(ic, NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); 4148
4149 // Push the arguments ("left-to-right").
4150 int arg_count = args->length();
4151 for (int i = 0; i < arg_count; i++) {
4152 VisitForStackValue(args->at(i));
4153 }
4154
4155 // Record source position of the IC call.
4156 SetSourcePosition(expr->position());
4157 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
4158 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
4159 __ CallStub(&stub);
4160
4161 // Restore context register. 4161 // Restore context register.
4162 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4162 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4163
4164 context()->DropAndPlug(1, r0);
4163 } else { 4165 } else {
4166 // Push the arguments ("left-to-right").
4167 for (int i = 0; i < arg_count; i++) {
4168 VisitForStackValue(args->at(i));
4169 }
4170
4164 // Call the C runtime function. 4171 // Call the C runtime function.
4165 __ CallRuntime(expr->function(), arg_count); 4172 __ CallRuntime(expr->function(), arg_count);
4173 context()->Plug(r0);
4166 } 4174 }
4167 context()->Plug(r0);
4168 } 4175 }
4169 4176
4170 4177
4171 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4178 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
4172 switch (expr->op()) { 4179 switch (expr->op()) {
4173 case Token::DELETE: { 4180 case Token::DELETE: {
4174 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4181 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4175 Property* property = expr->expression()->AsProperty(); 4182 Property* property = expr->expression()->AsProperty();
4176 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4183 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4177 4184
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
4397 4404
4398 4405
4399 __ bind(&stub_call); 4406 __ bind(&stub_call);
4400 __ mov(r1, r0); 4407 __ mov(r1, r0);
4401 __ mov(r0, Operand(Smi::FromInt(count_value))); 4408 __ mov(r0, Operand(Smi::FromInt(count_value)));
4402 4409
4403 // Record position before stub call. 4410 // Record position before stub call.
4404 SetSourcePosition(expr->position()); 4411 SetSourcePosition(expr->position());
4405 4412
4406 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); 4413 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
4407 CallIC(stub.GetCode(isolate()), 4414 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
4408 NOT_CONTEXTUAL,
4409 expr->CountBinOpFeedbackId());
4410 patch_site.EmitPatchInfo(); 4415 patch_site.EmitPatchInfo();
4411 __ bind(&done); 4416 __ bind(&done);
4412 4417
4413 // Store the value returned in r0. 4418 // Store the value returned in r0.
4414 switch (assign_type) { 4419 switch (assign_type) {
4415 case VARIABLE: 4420 case VARIABLE:
4416 if (expr->is_postfix()) { 4421 if (expr->is_postfix()) {
4417 { EffectContext context(this); 4422 { EffectContext context(this);
4418 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4423 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4419 Token::ASSIGN); 4424 Token::ASSIGN);
4420 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4425 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4421 context.Plug(r0); 4426 context.Plug(r0);
4422 } 4427 }
4423 // For all contexts except EffectConstant We have the result on 4428 // For all contexts except EffectConstant We have the result on
4424 // top of the stack. 4429 // top of the stack.
4425 if (!context()->IsEffect()) { 4430 if (!context()->IsEffect()) {
4426 context()->PlugTOS(); 4431 context()->PlugTOS();
4427 } 4432 }
4428 } else { 4433 } else {
4429 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4434 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4430 Token::ASSIGN); 4435 Token::ASSIGN);
4431 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4436 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4432 context()->Plug(r0); 4437 context()->Plug(r0);
4433 } 4438 }
4434 break; 4439 break;
4435 case NAMED_PROPERTY: { 4440 case NAMED_PROPERTY: {
4436 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); 4441 __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
4437 __ pop(r1); 4442 __ pop(r1);
4438 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4443 CallStoreIC(expr->CountStoreFeedbackId());
4439 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4444 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4440 if (expr->is_postfix()) { 4445 if (expr->is_postfix()) {
4441 if (!context()->IsEffect()) { 4446 if (!context()->IsEffect()) {
4442 context()->PlugTOS(); 4447 context()->PlugTOS();
4443 } 4448 }
4444 } else { 4449 } else {
4445 context()->Plug(r0); 4450 context()->Plug(r0);
4446 } 4451 }
4447 break; 4452 break;
4448 } 4453 }
4449 case KEYED_PROPERTY: { 4454 case KEYED_PROPERTY: {
4450 __ Pop(r2, r1); // r1 = key. r2 = receiver. 4455 __ Pop(r2, r1); // r1 = key. r2 = receiver.
4451 Handle<Code> ic = is_classic_mode() 4456 Handle<Code> ic = is_classic_mode()
4452 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4457 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4453 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4458 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4454 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4459 CallIC(ic, expr->CountStoreFeedbackId());
4455 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4460 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4456 if (expr->is_postfix()) { 4461 if (expr->is_postfix()) {
4457 if (!context()->IsEffect()) { 4462 if (!context()->IsEffect()) {
4458 context()->PlugTOS(); 4463 context()->PlugTOS();
4459 } 4464 }
4460 } else { 4465 } else {
4461 context()->Plug(r0); 4466 context()->Plug(r0);
4462 } 4467 }
4463 break; 4468 break;
4464 } 4469 }
4465 } 4470 }
4466 } 4471 }
4467 4472
4468 4473
4469 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4474 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4470 ASSERT(!context()->IsEffect()); 4475 ASSERT(!context()->IsEffect());
4471 ASSERT(!context()->IsTest()); 4476 ASSERT(!context()->IsTest());
4472 VariableProxy* proxy = expr->AsVariableProxy(); 4477 VariableProxy* proxy = expr->AsVariableProxy();
4473 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4478 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4474 Comment cmnt(masm_, "Global variable"); 4479 Comment cmnt(masm_, "[ Global variable");
4475 __ ldr(r0, GlobalObjectOperand()); 4480 __ ldr(r0, GlobalObjectOperand());
4476 __ mov(r2, Operand(proxy->name())); 4481 __ mov(r2, Operand(proxy->name()));
4477 // Use a regular load, not a contextual load, to avoid a reference 4482 // Use a regular load, not a contextual load, to avoid a reference
4478 // error. 4483 // error.
4479 CallLoadIC(NOT_CONTEXTUAL); 4484 CallLoadIC(NOT_CONTEXTUAL);
4480 PrepareForBailout(expr, TOS_REG); 4485 PrepareForBailout(expr, TOS_REG);
4481 context()->Plug(r0); 4486 context()->Plug(r0);
4482 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4487 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4488 Comment cmnt(masm_, "[ Lookup slot");
4483 Label done, slow; 4489 Label done, slow;
4484 4490
4485 // Generate code for loading from variables potentially shadowed 4491 // Generate code for loading from variables potentially shadowed
4486 // by eval-introduced variables. 4492 // by eval-introduced variables.
4487 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); 4493 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done);
4488 4494
4489 __ bind(&slow); 4495 __ bind(&slow);
4490 __ mov(r0, Operand(proxy->name())); 4496 __ mov(r0, Operand(proxy->name()));
4491 __ Push(cp, r0); 4497 __ Push(cp, r0);
4492 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 4498 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
4634 __ orr(r2, r0, Operand(r1)); 4640 __ orr(r2, r0, Operand(r1));
4635 patch_site.EmitJumpIfNotSmi(r2, &slow_case); 4641 patch_site.EmitJumpIfNotSmi(r2, &slow_case);
4636 __ cmp(r1, r0); 4642 __ cmp(r1, r0);
4637 Split(cond, if_true, if_false, NULL); 4643 Split(cond, if_true, if_false, NULL);
4638 __ bind(&slow_case); 4644 __ bind(&slow_case);
4639 } 4645 }
4640 4646
4641 // Record position and call the compare IC. 4647 // Record position and call the compare IC.
4642 SetSourcePosition(expr->position()); 4648 SetSourcePosition(expr->position());
4643 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 4649 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
4644 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4650 CallIC(ic, expr->CompareOperationFeedbackId());
4645 patch_site.EmitPatchInfo(); 4651 patch_site.EmitPatchInfo();
4646 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4652 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4647 __ cmp(r0, Operand::Zero()); 4653 __ cmp(r0, Operand::Zero());
4648 Split(cond, if_true, if_false, fall_through); 4654 Split(cond, if_true, if_false, fall_through);
4649 } 4655 }
4650 } 4656 }
4651 4657
4652 // Convert the result of the comparison into one expected for this 4658 // Convert the result of the comparison into one expected for this
4653 // expression's context. 4659 // expression's context.
4654 context()->Plug(if_true, if_false); 4660 context()->Plug(if_true, if_false);
(...skipping 14 matching lines...) Expand all
4669 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4675 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4670 if (expr->op() == Token::EQ_STRICT) { 4676 if (expr->op() == Token::EQ_STRICT) {
4671 Heap::RootListIndex nil_value = nil == kNullValue ? 4677 Heap::RootListIndex nil_value = nil == kNullValue ?
4672 Heap::kNullValueRootIndex : 4678 Heap::kNullValueRootIndex :
4673 Heap::kUndefinedValueRootIndex; 4679 Heap::kUndefinedValueRootIndex;
4674 __ LoadRoot(r1, nil_value); 4680 __ LoadRoot(r1, nil_value);
4675 __ cmp(r0, r1); 4681 __ cmp(r0, r1);
4676 Split(eq, if_true, if_false, fall_through); 4682 Split(eq, if_true, if_false, fall_through);
4677 } else { 4683 } else {
4678 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4684 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
4679 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4685 CallIC(ic, expr->CompareOperationFeedbackId());
4680 __ cmp(r0, Operand(0)); 4686 __ cmp(r0, Operand(0));
4681 Split(ne, if_true, if_false, fall_through); 4687 Split(ne, if_true, if_false, fall_through);
4682 } 4688 }
4683 context()->Plug(if_true, if_false); 4689 context()->Plug(if_true, if_false);
4684 } 4690 }
4685 4691
4686 4692
4687 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4693 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4688 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4694 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4689 context()->Plug(r0); 4695 context()->Plug(r0);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
4912 ASSERT(Memory::uint32_at(interrupt_address_pointer) == 4918 ASSERT(Memory::uint32_at(interrupt_address_pointer) ==
4913 reinterpret_cast<uint32_t>( 4919 reinterpret_cast<uint32_t>(
4914 isolate->builtins()->OsrAfterStackCheck()->entry())); 4920 isolate->builtins()->OsrAfterStackCheck()->entry()));
4915 return OSR_AFTER_STACK_CHECK; 4921 return OSR_AFTER_STACK_CHECK;
4916 } 4922 }
4917 4923
4918 4924
4919 } } // namespace v8::internal 4925 } } // namespace v8::internal
4920 4926
4921 #endif // V8_TARGET_ARCH_ARM 4927 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/deoptimizer-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698