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

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

Issue 181453002: Reset trunk to 3.24.35.4 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
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/mips/debug-mips.cc ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 // o fp: our caller's frame pointer 131 // o fp: our caller's frame pointer
132 // o sp: stack pointer 132 // o sp: stack pointer
133 // o ra: return address 133 // o ra: return address
134 // 134 //
135 // The function builds a JS frame. Please see JavaScriptFrameConstants in 135 // The function builds a JS frame. Please see JavaScriptFrameConstants in
136 // frames-mips.h for its layout. 136 // frames-mips.h for its layout.
137 void FullCodeGenerator::Generate() { 137 void FullCodeGenerator::Generate() {
138 CompilationInfo* info = info_; 138 CompilationInfo* info = info_;
139 handler_table_ = 139 handler_table_ =
140 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 140 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
141
142 InitializeFeedbackVector();
143
144 profiling_counter_ = isolate()->factory()->NewCell( 141 profiling_counter_ = isolate()->factory()->NewCell(
145 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 142 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
146 SetFunctionPosition(function()); 143 SetFunctionPosition(function());
147 Comment cmnt(masm_, "[ function compiled by full code generator"); 144 Comment cmnt(masm_, "[ function compiled by full code generator");
148 145
149 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 146 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
150 147
151 #ifdef DEBUG 148 #ifdef DEBUG
152 if (strlen(FLAG_stop_at) > 0 && 149 if (strlen(FLAG_stop_at) > 0 &&
153 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 150 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 } 672 }
676 } 673 }
677 674
678 675
679 void FullCodeGenerator::DoTest(Expression* condition, 676 void FullCodeGenerator::DoTest(Expression* condition,
680 Label* if_true, 677 Label* if_true,
681 Label* if_false, 678 Label* if_false,
682 Label* fall_through) { 679 Label* fall_through) {
683 __ mov(a0, result_register()); 680 __ mov(a0, result_register());
684 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 681 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
685 CallIC(ic, condition->test_id()); 682 CallIC(ic, NOT_CONTEXTUAL, condition->test_id());
686 __ mov(at, zero_reg); 683 __ mov(at, zero_reg);
687 Split(ne, v0, Operand(at), if_true, if_false, fall_through); 684 Split(ne, v0, Operand(at), if_true, if_false, fall_through);
688 } 685 }
689 686
690 687
691 void FullCodeGenerator::Split(Condition cc, 688 void FullCodeGenerator::Split(Condition cc,
692 Register lhs, 689 Register lhs,
693 const Operand& rhs, 690 const Operand& rhs,
694 Label* if_true, 691 Label* if_true,
695 Label* if_false, 692 Label* if_false,
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 __ Branch(&next_test, ne, a1, Operand(a0)); 1037 __ Branch(&next_test, ne, a1, Operand(a0));
1041 __ Drop(1); // Switch value is no longer needed. 1038 __ Drop(1); // Switch value is no longer needed.
1042 __ Branch(clause->body_target()); 1039 __ Branch(clause->body_target());
1043 1040
1044 __ bind(&slow_case); 1041 __ bind(&slow_case);
1045 } 1042 }
1046 1043
1047 // Record position before stub call for type feedback. 1044 // Record position before stub call for type feedback.
1048 SetSourcePosition(clause->position()); 1045 SetSourcePosition(clause->position());
1049 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 1046 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
1050 CallIC(ic, clause->CompareId()); 1047 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId());
1051 patch_site.EmitPatchInfo(); 1048 patch_site.EmitPatchInfo();
1052 1049
1053 Label skip; 1050 Label skip;
1054 __ Branch(&skip); 1051 __ Branch(&skip);
1055 PrepareForBailout(clause, TOS_REG); 1052 PrepareForBailout(clause, TOS_REG);
1056 __ LoadRoot(at, Heap::kTrueValueRootIndex); 1053 __ LoadRoot(at, Heap::kTrueValueRootIndex);
1057 __ Branch(&next_test, ne, v0, Operand(at)); 1054 __ Branch(&next_test, ne, v0, Operand(at));
1058 __ Drop(1); 1055 __ Drop(1);
1059 __ Branch(clause->body_target()); 1056 __ Branch(clause->body_target());
1060 __ bind(&skip); 1057 __ bind(&skip);
(...skipping 22 matching lines...) Expand all
1083 VisitStatements(clause->statements()); 1080 VisitStatements(clause->statements());
1084 } 1081 }
1085 1082
1086 __ bind(nested_statement.break_label()); 1083 __ bind(nested_statement.break_label());
1087 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1084 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1088 } 1085 }
1089 1086
1090 1087
1091 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1088 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1092 Comment cmnt(masm_, "[ ForInStatement"); 1089 Comment cmnt(masm_, "[ ForInStatement");
1093 int slot = stmt->ForInFeedbackSlot();
1094 SetStatementPosition(stmt); 1090 SetStatementPosition(stmt);
1095 1091
1096 Label loop, exit; 1092 Label loop, exit;
1097 ForIn loop_statement(this, stmt); 1093 ForIn loop_statement(this, stmt);
1098 increment_loop_depth(); 1094 increment_loop_depth();
1099 1095
1100 // Get the object to enumerate over. If the object is null or undefined, skip 1096 // Get the object to enumerate over. If the object is null or undefined, skip
1101 // over the loop. See ECMA-262 version 5, section 12.6.4. 1097 // over the loop. See ECMA-262 version 5, section 12.6.4.
1102 VisitForAccumulatorValue(stmt->enumerable()); 1098 VisitForAccumulatorValue(stmt->enumerable());
1103 __ mov(a0, result_register()); // Result as param to InvokeBuiltin below. 1099 __ mov(a0, result_register()); // Result as param to InvokeBuiltin below.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 __ jmp(&loop); 1165 __ jmp(&loop);
1170 1166
1171 __ bind(&no_descriptors); 1167 __ bind(&no_descriptors);
1172 __ Drop(1); 1168 __ Drop(1);
1173 __ jmp(&exit); 1169 __ jmp(&exit);
1174 1170
1175 // We got a fixed array in register v0. Iterate through that. 1171 // We got a fixed array in register v0. Iterate through that.
1176 Label non_proxy; 1172 Label non_proxy;
1177 __ bind(&fixed_array); 1173 __ bind(&fixed_array);
1178 1174
1179 Handle<Object> feedback = Handle<Object>( 1175 Handle<Cell> cell = isolate()->factory()->NewCell(
1180 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker), 1176 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker),
1181 isolate()); 1177 isolate()));
1182 StoreFeedbackVectorSlot(slot, feedback); 1178 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell);
1183 __ li(a1, FeedbackVector()); 1179 __ li(a1, cell);
1184 __ li(a2, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker))); 1180 __ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker)));
1185 __ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot))); 1181 __ sw(a2, FieldMemOperand(a1, Cell::kValueOffset));
1186 1182
1187 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check 1183 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
1188 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object 1184 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
1189 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1185 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1190 __ GetObjectType(a2, a3, a3); 1186 __ GetObjectType(a2, a3, a3);
1191 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE)); 1187 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE));
1192 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy 1188 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy
1193 __ bind(&non_proxy); 1189 __ bind(&non_proxy);
1194 __ Push(a1, v0); // Smi and array 1190 __ Push(a1, v0); // Smi and array
1195 __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); 1191 __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset));
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1483 1479
1484 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1480 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
1485 // Record position before possible IC call. 1481 // Record position before possible IC call.
1486 SetSourcePosition(proxy->position()); 1482 SetSourcePosition(proxy->position());
1487 Variable* var = proxy->var(); 1483 Variable* var = proxy->var();
1488 1484
1489 // Three cases: global variables, lookup variables, and all other types of 1485 // Three cases: global variables, lookup variables, and all other types of
1490 // variables. 1486 // variables.
1491 switch (var->location()) { 1487 switch (var->location()) {
1492 case Variable::UNALLOCATED: { 1488 case Variable::UNALLOCATED: {
1493 Comment cmnt(masm_, "[ Global variable"); 1489 Comment cmnt(masm_, "Global variable");
1494 // Use inline caching. Variable name is passed in a2 and the global 1490 // Use inline caching. Variable name is passed in a2 and the global
1495 // object (receiver) in a0. 1491 // object (receiver) in a0.
1496 __ lw(a0, GlobalObjectOperand()); 1492 __ lw(a0, GlobalObjectOperand());
1497 __ li(a2, Operand(var->name())); 1493 __ li(a2, Operand(var->name()));
1498 CallLoadIC(CONTEXTUAL); 1494 CallLoadIC(CONTEXTUAL);
1499 context()->Plug(v0); 1495 context()->Plug(v0);
1500 break; 1496 break;
1501 } 1497 }
1502 1498
1503 case Variable::PARAMETER: 1499 case Variable::PARAMETER:
1504 case Variable::LOCAL: 1500 case Variable::LOCAL:
1505 case Variable::CONTEXT: { 1501 case Variable::CONTEXT: {
1506 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1502 Comment cmnt(masm_, var->IsContextSlot()
1507 : "[ Stack variable"); 1503 ? "Context variable"
1504 : "Stack variable");
1508 if (var->binding_needs_init()) { 1505 if (var->binding_needs_init()) {
1509 // var->scope() may be NULL when the proxy is located in eval code and 1506 // var->scope() may be NULL when the proxy is located in eval code and
1510 // refers to a potential outside binding. Currently those bindings are 1507 // refers to a potential outside binding. Currently those bindings are
1511 // always looked up dynamically, i.e. in that case 1508 // always looked up dynamically, i.e. in that case
1512 // var->location() == LOOKUP. 1509 // var->location() == LOOKUP.
1513 // always holds. 1510 // always holds.
1514 ASSERT(var->scope() != NULL); 1511 ASSERT(var->scope() != NULL);
1515 1512
1516 // Check if the binding really needs an initialization check. The check 1513 // Check if the binding really needs an initialization check. The check
1517 // can be skipped in the following situation: we have a LET or CONST 1514 // can be skipped in the following situation: we have a LET or CONST
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 } 1559 }
1563 context()->Plug(v0); 1560 context()->Plug(v0);
1564 break; 1561 break;
1565 } 1562 }
1566 } 1563 }
1567 context()->Plug(var); 1564 context()->Plug(var);
1568 break; 1565 break;
1569 } 1566 }
1570 1567
1571 case Variable::LOOKUP: { 1568 case Variable::LOOKUP: {
1572 Comment cmnt(masm_, "[ Lookup variable");
1573 Label done, slow; 1569 Label done, slow;
1574 // Generate code for loading from variables potentially shadowed 1570 // Generate code for loading from variables potentially shadowed
1575 // by eval-introduced variables. 1571 // by eval-introduced variables.
1576 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done); 1572 EmitDynamicLookupFastCase(var, NOT_INSIDE_TYPEOF, &slow, &done);
1577 __ bind(&slow); 1573 __ bind(&slow);
1574 Comment cmnt(masm_, "Lookup variable");
1578 __ li(a1, Operand(var->name())); 1575 __ li(a1, Operand(var->name()));
1579 __ Push(cp, a1); // Context and name. 1576 __ Push(cp, a1); // Context and name.
1580 __ CallRuntime(Runtime::kLoadContextSlot, 2); 1577 __ CallRuntime(Runtime::kLoadContextSlot, 2);
1581 __ bind(&done); 1578 __ bind(&done);
1582 context()->Plug(v0); 1579 context()->Plug(v0);
1583 } 1580 }
1584 } 1581 }
1585 } 1582 }
1586 1583
1587 1584
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1696 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1700 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1697 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
1701 // Fall through. 1698 // Fall through.
1702 case ObjectLiteral::Property::COMPUTED: 1699 case ObjectLiteral::Property::COMPUTED:
1703 if (key->value()->IsInternalizedString()) { 1700 if (key->value()->IsInternalizedString()) {
1704 if (property->emit_store()) { 1701 if (property->emit_store()) {
1705 VisitForAccumulatorValue(value); 1702 VisitForAccumulatorValue(value);
1706 __ mov(a0, result_register()); 1703 __ mov(a0, result_register());
1707 __ li(a2, Operand(key->value())); 1704 __ li(a2, Operand(key->value()));
1708 __ lw(a1, MemOperand(sp)); 1705 __ lw(a1, MemOperand(sp));
1709 CallStoreIC(key->LiteralFeedbackId()); 1706 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId());
1710 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1707 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1711 } else { 1708 } else {
1712 VisitForEffect(value); 1709 VisitForEffect(value);
1713 } 1710 }
1714 break; 1711 break;
1715 } 1712 }
1716 // Duplicate receiver on stack. 1713 // Duplicate receiver on stack.
1717 __ lw(a0, MemOperand(sp)); 1714 __ lw(a0, MemOperand(sp));
1718 __ push(a0); 1715 __ push(a0);
1719 VisitForStackValue(key); 1716 VisitForStackValue(key);
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 __ bind(&l_next); 2104 __ bind(&l_next);
2108 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" 2105 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
2109 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2106 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
2110 __ Push(a2, a3, a0); // "next", iter, received 2107 __ Push(a2, a3, a0); // "next", iter, received
2111 2108
2112 // result = receiver[f](arg); 2109 // result = receiver[f](arg);
2113 __ bind(&l_call); 2110 __ bind(&l_call);
2114 __ lw(a1, MemOperand(sp, kPointerSize)); 2111 __ lw(a1, MemOperand(sp, kPointerSize));
2115 __ lw(a0, MemOperand(sp, 2 * kPointerSize)); 2112 __ lw(a0, MemOperand(sp, 2 * kPointerSize));
2116 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2113 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2117 CallIC(ic, TypeFeedbackId::None()); 2114 CallIC(ic, NOT_CONTEXTUAL, TypeFeedbackId::None());
2118 __ mov(a0, v0); 2115 __ mov(a0, v0);
2119 __ mov(a1, a0); 2116 __ mov(a1, a0);
2120 __ sw(a1, MemOperand(sp, 2 * kPointerSize)); 2117 __ sw(a1, MemOperand(sp, 2 * kPointerSize));
2121 CallFunctionStub stub(1, CALL_AS_METHOD); 2118 CallFunctionStub stub(1, CALL_AS_METHOD);
2122 __ CallStub(&stub); 2119 __ CallStub(&stub);
2123 2120
2124 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2121 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2125 __ Drop(1); // The function is still on the stack; drop it. 2122 __ Drop(1); // The function is still on the stack; drop it.
2126 2123
2127 // if (!result.done) goto l_try; 2124 // if (!result.done) goto l_try;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2305 // Call load IC. It has arguments receiver and property name a0 and a2. 2302 // Call load IC. It has arguments receiver and property name a0 and a2.
2306 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2303 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2307 } 2304 }
2308 2305
2309 2306
2310 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2307 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2311 SetSourcePosition(prop->position()); 2308 SetSourcePosition(prop->position());
2312 __ mov(a0, result_register()); 2309 __ mov(a0, result_register());
2313 // Call keyed load IC. It has arguments key and receiver in a0 and a1. 2310 // Call keyed load IC. It has arguments key and receiver in a0 and a1.
2314 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2311 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2315 CallIC(ic, prop->PropertyFeedbackId()); 2312 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2316 } 2313 }
2317 2314
2318 2315
2319 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2316 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2320 Token::Value op, 2317 Token::Value op,
2321 OverwriteMode mode, 2318 OverwriteMode mode,
2322 Expression* left_expr, 2319 Expression* left_expr,
2323 Expression* right_expr) { 2320 Expression* right_expr) {
2324 Label done, smi_case, stub_call; 2321 Label done, smi_case, stub_call;
2325 2322
2326 Register scratch1 = a2; 2323 Register scratch1 = a2;
2327 Register scratch2 = a3; 2324 Register scratch2 = a3;
2328 2325
2329 // Get the arguments. 2326 // Get the arguments.
2330 Register left = a1; 2327 Register left = a1;
2331 Register right = a0; 2328 Register right = a0;
2332 __ pop(left); 2329 __ pop(left);
2333 __ mov(a0, result_register()); 2330 __ mov(a0, result_register());
2334 2331
2335 // Perform combined smi check on both operands. 2332 // Perform combined smi check on both operands.
2336 __ Or(scratch1, left, Operand(right)); 2333 __ Or(scratch1, left, Operand(right));
2337 STATIC_ASSERT(kSmiTag == 0); 2334 STATIC_ASSERT(kSmiTag == 0);
2338 JumpPatchSite patch_site(masm_); 2335 JumpPatchSite patch_site(masm_);
2339 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 2336 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2340 2337
2341 __ bind(&stub_call); 2338 __ bind(&stub_call);
2342 BinaryOpICStub stub(op, mode); 2339 BinaryOpICStub stub(op, mode);
2343 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); 2340 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL,
2341 expr->BinaryOperationFeedbackId());
2344 patch_site.EmitPatchInfo(); 2342 patch_site.EmitPatchInfo();
2345 __ jmp(&done); 2343 __ jmp(&done);
2346 2344
2347 __ bind(&smi_case); 2345 __ bind(&smi_case);
2348 // Smi case. This code works the same way as the smi-smi case in the type 2346 // Smi case. This code works the same way as the smi-smi case in the type
2349 // recording binary operation stub, see 2347 // recording binary operation stub, see
2350 switch (op) { 2348 switch (op) {
2351 case Token::SAR: 2349 case Token::SAR:
2352 __ GetLeastBitsFromSmi(scratch1, right, 5); 2350 __ GetLeastBitsFromSmi(scratch1, right, 5);
2353 __ srav(right, left, scratch1); 2351 __ srav(right, left, scratch1);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2412 } 2410 }
2413 2411
2414 2412
2415 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 2413 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
2416 Token::Value op, 2414 Token::Value op,
2417 OverwriteMode mode) { 2415 OverwriteMode mode) {
2418 __ mov(a0, result_register()); 2416 __ mov(a0, result_register());
2419 __ pop(a1); 2417 __ pop(a1);
2420 BinaryOpICStub stub(op, mode); 2418 BinaryOpICStub stub(op, mode);
2421 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2419 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2422 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId()); 2420 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL,
2421 expr->BinaryOperationFeedbackId());
2423 patch_site.EmitPatchInfo(); 2422 patch_site.EmitPatchInfo();
2424 context()->Plug(v0); 2423 context()->Plug(v0);
2425 } 2424 }
2426 2425
2427 2426
2428 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2427 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2429 // Invalid left-hand sides are rewritten by the parser to have a 'throw 2428 // Invalid left-hand sides are rewritten by the parser to have a 'throw
2430 // ReferenceError' on the left-hand side. 2429 // ReferenceError' on the left-hand side.
2431 if (!expr->IsValidLeftHandSide()) { 2430 if (!expr->IsValidLeftHandSide()) {
2432 VisitForEffect(expr); 2431 VisitForEffect(expr);
(...skipping 17 matching lines...) Expand all
2450 EffectContext context(this); 2449 EffectContext context(this);
2451 EmitVariableAssignment(var, Token::ASSIGN); 2450 EmitVariableAssignment(var, Token::ASSIGN);
2452 break; 2451 break;
2453 } 2452 }
2454 case NAMED_PROPERTY: { 2453 case NAMED_PROPERTY: {
2455 __ push(result_register()); // Preserve value. 2454 __ push(result_register()); // Preserve value.
2456 VisitForAccumulatorValue(prop->obj()); 2455 VisitForAccumulatorValue(prop->obj());
2457 __ mov(a1, result_register()); 2456 __ mov(a1, result_register());
2458 __ pop(a0); // Restore value. 2457 __ pop(a0); // Restore value.
2459 __ li(a2, Operand(prop->key()->AsLiteral()->value())); 2458 __ li(a2, Operand(prop->key()->AsLiteral()->value()));
2460 CallStoreIC(); 2459 CallStoreIC(NOT_CONTEXTUAL);
2461 break; 2460 break;
2462 } 2461 }
2463 case KEYED_PROPERTY: { 2462 case KEYED_PROPERTY: {
2464 __ push(result_register()); // Preserve value. 2463 __ push(result_register()); // Preserve value.
2465 VisitForStackValue(prop->obj()); 2464 VisitForStackValue(prop->obj());
2466 VisitForAccumulatorValue(prop->key()); 2465 VisitForAccumulatorValue(prop->key());
2467 __ mov(a1, result_register()); 2466 __ mov(a1, result_register());
2468 __ Pop(a0, a2); // a0 = restored value. 2467 __ Pop(a0, a2); // a0 = restored value.
2469 Handle<Code> ic = is_classic_mode() 2468 Handle<Code> ic = is_classic_mode()
2470 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2469 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2471 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2470 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2472 CallIC(ic); 2471 CallIC(ic);
2473 break; 2472 break;
2474 } 2473 }
2475 } 2474 }
2476 context()->Plug(v0); 2475 context()->Plug(v0);
2477 } 2476 }
2478 2477
2479 2478
2480 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2481 Variable* var, MemOperand location) {
2482 __ sw(result_register(), location);
2483 if (var->IsContextSlot()) {
2484 // RecordWrite may destroy all its register arguments.
2485 __ Move(a3, result_register());
2486 int offset = Context::SlotOffset(var->index());
2487 __ RecordWriteContextSlot(
2488 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
2489 }
2490 }
2491
2492
2493 void FullCodeGenerator::EmitCallStoreContextSlot(
2494 Handle<String> name, LanguageMode mode) {
2495 __ li(a1, Operand(name));
2496 __ li(a0, Operand(Smi::FromInt(mode)));
2497 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode.
2498 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2499 }
2500
2501
2502 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2479 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2503 Token::Value op) { 2480 Token::Value op) {
2504 if (var->IsUnallocated()) { 2481 if (var->IsUnallocated()) {
2505 // Global var, const, or let. 2482 // Global var, const, or let.
2506 __ mov(a0, result_register()); 2483 __ mov(a0, result_register());
2507 __ li(a2, Operand(var->name())); 2484 __ li(a2, Operand(var->name()));
2508 __ lw(a1, GlobalObjectOperand()); 2485 __ lw(a1, GlobalObjectOperand());
2509 CallStoreIC(); 2486 CallStoreIC(CONTEXTUAL);
2510
2511 } else if (op == Token::INIT_CONST) { 2487 } else if (op == Token::INIT_CONST) {
2512 // Const initializers need a write barrier. 2488 // Const initializers need a write barrier.
2513 ASSERT(!var->IsParameter()); // No const parameters. 2489 ASSERT(!var->IsParameter()); // No const parameters.
2514 if (var->IsLookupSlot()) { 2490 if (var->IsStackLocal()) {
2491 Label skip;
2492 __ lw(a1, StackOperand(var));
2493 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2494 __ Branch(&skip, ne, a1, Operand(t0));
2495 __ sw(result_register(), StackOperand(var));
2496 __ bind(&skip);
2497 } else {
2498 ASSERT(var->IsContextSlot() || var->IsLookupSlot());
2499 // Like var declarations, const declarations are hoisted to function
2500 // scope. However, unlike var initializers, const initializers are
2501 // able to drill a hole to that function context, even from inside a
2502 // 'with' context. We thus bypass the normal static scope lookup for
2503 // var->IsContextSlot().
2515 __ li(a0, Operand(var->name())); 2504 __ li(a0, Operand(var->name()));
2516 __ Push(v0, cp, a0); // Context and name. 2505 __ Push(v0, cp, a0); // Context and name.
2517 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 2506 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
2518 } else {
2519 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2520 Label skip;
2521 MemOperand location = VarOperand(var, a1);
2522 __ lw(a2, location);
2523 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2524 __ Branch(&skip, ne, a2, Operand(at));
2525 EmitStoreToStackLocalOrContextSlot(var, location);
2526 __ bind(&skip);
2527 } 2507 }
2528 2508
2529 } else if (var->mode() == LET && op != Token::INIT_LET) { 2509 } else if (var->mode() == LET && op != Token::INIT_LET) {
2530 // Non-initializing assignment to let variable needs a write barrier. 2510 // Non-initializing assignment to let variable needs a write barrier.
2531 if (var->IsLookupSlot()) { 2511 if (var->IsLookupSlot()) {
2532 EmitCallStoreContextSlot(var->name(), language_mode()); 2512 __ li(a1, Operand(var->name()));
2513 __ li(a0, Operand(Smi::FromInt(language_mode())));
2514 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode.
2515 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2533 } else { 2516 } else {
2534 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2517 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2535 Label assign; 2518 Label assign;
2536 MemOperand location = VarOperand(var, a1); 2519 MemOperand location = VarOperand(var, a1);
2537 __ lw(a3, location); 2520 __ lw(a3, location);
2538 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2521 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2539 __ Branch(&assign, ne, a3, Operand(t0)); 2522 __ Branch(&assign, ne, a3, Operand(t0));
2540 __ li(a3, Operand(var->name())); 2523 __ li(a3, Operand(var->name()));
2541 __ push(a3); 2524 __ push(a3);
2542 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2525 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2543 // Perform the assignment. 2526 // Perform the assignment.
2544 __ bind(&assign); 2527 __ bind(&assign);
2545 EmitStoreToStackLocalOrContextSlot(var, location); 2528 __ sw(result_register(), location);
2529 if (var->IsContextSlot()) {
2530 // RecordWrite may destroy all its register arguments.
2531 __ mov(a3, result_register());
2532 int offset = Context::SlotOffset(var->index());
2533 __ RecordWriteContextSlot(
2534 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
2535 }
2546 } 2536 }
2547 2537
2548 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { 2538 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) {
2549 // Assignment to var or initializing assignment to let/const 2539 // Assignment to var or initializing assignment to let/const
2550 // in harmony mode. 2540 // in harmony mode.
2551 if (var->IsLookupSlot()) { 2541 if (var->IsStackAllocated() || var->IsContextSlot()) {
2552 EmitCallStoreContextSlot(var->name(), language_mode());
2553 } else {
2554 ASSERT((var->IsStackAllocated() || var->IsContextSlot()));
2555 MemOperand location = VarOperand(var, a1); 2542 MemOperand location = VarOperand(var, a1);
2556 if (generate_debug_code_ && op == Token::INIT_LET) { 2543 if (generate_debug_code_ && op == Token::INIT_LET) {
2557 // Check for an uninitialized let binding. 2544 // Check for an uninitialized let binding.
2558 __ lw(a2, location); 2545 __ lw(a2, location);
2559 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2546 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2560 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0)); 2547 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0));
2561 } 2548 }
2562 EmitStoreToStackLocalOrContextSlot(var, location); 2549 // Perform the assignment.
2550 __ sw(v0, location);
2551 if (var->IsContextSlot()) {
2552 __ mov(a3, v0);
2553 int offset = Context::SlotOffset(var->index());
2554 __ RecordWriteContextSlot(
2555 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
2556 }
2557 } else {
2558 ASSERT(var->IsLookupSlot());
2559 __ li(a1, Operand(var->name()));
2560 __ li(a0, Operand(Smi::FromInt(language_mode())));
2561 __ Push(v0, cp, a1, a0); // Value, context, name, strict mode.
2562 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2563 } 2563 }
2564 } 2564 }
2565 // Non-initializing assignments to consts are ignored. 2565 // Non-initializing assignments to consts are ignored.
2566 } 2566 }
2567 2567
2568 2568
2569 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2569 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2570 // Assignment to a property, using a named store IC. 2570 // Assignment to a property, using a named store IC.
2571 Property* prop = expr->target()->AsProperty(); 2571 Property* prop = expr->target()->AsProperty();
2572 ASSERT(prop != NULL); 2572 ASSERT(prop != NULL);
2573 ASSERT(prop->key()->AsLiteral() != NULL); 2573 ASSERT(prop->key()->AsLiteral() != NULL);
2574 2574
2575 // Record source code position before IC call. 2575 // Record source code position before IC call.
2576 SetSourcePosition(expr->position()); 2576 SetSourcePosition(expr->position());
2577 __ mov(a0, result_register()); // Load the value. 2577 __ mov(a0, result_register()); // Load the value.
2578 __ li(a2, Operand(prop->key()->AsLiteral()->value())); 2578 __ li(a2, Operand(prop->key()->AsLiteral()->value()));
2579 __ pop(a1); 2579 __ pop(a1);
2580 2580
2581 CallStoreIC(expr->AssignmentFeedbackId()); 2581 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId());
2582 2582
2583 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2583 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2584 context()->Plug(v0); 2584 context()->Plug(v0);
2585 } 2585 }
2586 2586
2587 2587
2588 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2588 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2589 // Assignment to a property, using a keyed store IC. 2589 // Assignment to a property, using a keyed store IC.
2590 2590
2591 // Record source code position before IC call. 2591 // Record source code position before IC call.
2592 SetSourcePosition(expr->position()); 2592 SetSourcePosition(expr->position());
2593 // Call keyed store IC. 2593 // Call keyed store IC.
2594 // The arguments are: 2594 // The arguments are:
2595 // - a0 is the value, 2595 // - a0 is the value,
2596 // - a1 is the key, 2596 // - a1 is the key,
2597 // - a2 is the receiver. 2597 // - a2 is the receiver.
2598 __ mov(a0, result_register()); 2598 __ mov(a0, result_register());
2599 __ Pop(a2, a1); // a1 = key. 2599 __ Pop(a2, a1); // a1 = key.
2600 2600
2601 Handle<Code> ic = is_classic_mode() 2601 Handle<Code> ic = is_classic_mode()
2602 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2602 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2603 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2603 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2604 CallIC(ic, expr->AssignmentFeedbackId()); 2604 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId());
2605 2605
2606 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2606 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2607 context()->Plug(v0); 2607 context()->Plug(v0);
2608 } 2608 }
2609 2609
2610 2610
2611 void FullCodeGenerator::VisitProperty(Property* expr) { 2611 void FullCodeGenerator::VisitProperty(Property* expr) {
2612 Comment cmnt(masm_, "[ Property"); 2612 Comment cmnt(masm_, "[ Property");
2613 Expression* key = expr->key(); 2613 Expression* key = expr->key();
2614 2614
2615 if (key->IsPropertyName()) { 2615 if (key->IsPropertyName()) {
2616 VisitForAccumulatorValue(expr->obj()); 2616 VisitForAccumulatorValue(expr->obj());
2617 EmitNamedPropertyLoad(expr); 2617 EmitNamedPropertyLoad(expr);
2618 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2618 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2619 context()->Plug(v0); 2619 context()->Plug(v0);
2620 } else { 2620 } else {
2621 VisitForStackValue(expr->obj()); 2621 VisitForStackValue(expr->obj());
2622 VisitForAccumulatorValue(expr->key()); 2622 VisitForAccumulatorValue(expr->key());
2623 __ pop(a1); 2623 __ pop(a1);
2624 EmitKeyedPropertyLoad(expr); 2624 EmitKeyedPropertyLoad(expr);
2625 context()->Plug(v0); 2625 context()->Plug(v0);
2626 } 2626 }
2627 } 2627 }
2628 2628
2629 2629
2630 void FullCodeGenerator::CallIC(Handle<Code> code, 2630 void FullCodeGenerator::CallIC(Handle<Code> code,
2631 ContextualMode mode,
2631 TypeFeedbackId id) { 2632 TypeFeedbackId id) {
2632 ic_total_count_++; 2633 ic_total_count_++;
2634 ASSERT(mode != CONTEXTUAL || id.IsNone());
2633 __ Call(code, RelocInfo::CODE_TARGET, id); 2635 __ Call(code, RelocInfo::CODE_TARGET, id);
2634 } 2636 }
2635 2637
2636 2638
2637 // Code common for calls using the IC. 2639 // Code common for calls using the IC.
2638 void FullCodeGenerator::EmitCallWithIC(Call* expr) { 2640 void FullCodeGenerator::EmitCallWithIC(Call* expr) {
2639 Expression* callee = expr->expression(); 2641 Expression* callee = expr->expression();
2640 ZoneList<Expression*>* args = expr->arguments(); 2642 ZoneList<Expression*>* args = expr->arguments();
2641 int arg_count = args->length(); 2643 int arg_count = args->length();
2642 2644
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2732 int arg_count = args->length(); 2734 int arg_count = args->length();
2733 { PreservePositionScope scope(masm()->positions_recorder()); 2735 { PreservePositionScope scope(masm()->positions_recorder());
2734 for (int i = 0; i < arg_count; i++) { 2736 for (int i = 0; i < arg_count; i++) {
2735 VisitForStackValue(args->at(i)); 2737 VisitForStackValue(args->at(i));
2736 } 2738 }
2737 } 2739 }
2738 // Record source position for debugger. 2740 // Record source position for debugger.
2739 SetSourcePosition(expr->position()); 2741 SetSourcePosition(expr->position());
2740 2742
2741 Handle<Object> uninitialized = 2743 Handle<Object> uninitialized =
2742 TypeFeedbackInfo::UninitializedSentinel(isolate()); 2744 TypeFeedbackCells::UninitializedSentinel(isolate());
2743 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized); 2745 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
2744 __ li(a2, FeedbackVector()); 2746 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell);
2745 __ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot()))); 2747 __ li(a2, Operand(cell));
2746 2748
2747 // Record call targets in unoptimized code. 2749 // Record call targets in unoptimized code.
2748 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); 2750 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2749 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2751 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2750 __ CallStub(&stub); 2752 __ CallStub(&stub, expr->CallFeedbackId());
2751 RecordJSReturnSite(expr); 2753 RecordJSReturnSite(expr);
2752 // Restore context register. 2754 // Restore context register.
2753 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2755 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2754 context()->DropAndPlug(1, v0); 2756 context()->DropAndPlug(1, v0);
2755 } 2757 }
2756 2758
2757 2759
2758 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2760 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2759 // t2: copy of the first argument or undefined if it doesn't exist. 2761 // t2: copy of the first argument or undefined if it doesn't exist.
2760 if (arg_count > 0) { 2762 if (arg_count > 0) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2919 // Call the construct call builtin that handles allocation and 2921 // Call the construct call builtin that handles allocation and
2920 // constructor invocation. 2922 // constructor invocation.
2921 SetSourcePosition(expr->position()); 2923 SetSourcePosition(expr->position());
2922 2924
2923 // Load function and argument count into a1 and a0. 2925 // Load function and argument count into a1 and a0.
2924 __ li(a0, Operand(arg_count)); 2926 __ li(a0, Operand(arg_count));
2925 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2927 __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
2926 2928
2927 // Record call targets in unoptimized code. 2929 // Record call targets in unoptimized code.
2928 Handle<Object> uninitialized = 2930 Handle<Object> uninitialized =
2929 TypeFeedbackInfo::UninitializedSentinel(isolate()); 2931 TypeFeedbackCells::UninitializedSentinel(isolate());
2930 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized); 2932 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized);
2931 __ li(a2, FeedbackVector()); 2933 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell);
2932 __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot()))); 2934 __ li(a2, Operand(cell));
2933 2935
2934 CallConstructStub stub(RECORD_CALL_TARGET); 2936 CallConstructStub stub(RECORD_CALL_TARGET);
2935 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2937 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2936 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2938 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2937 context()->Plug(v0); 2939 context()->Plug(v0);
2938 } 2940 }
2939 2941
2940 2942
2941 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2943 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2942 ZoneList<Expression*>* args = expr->arguments(); 2944 ZoneList<Expression*>* args = expr->arguments();
(...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after
4462 } 4464 }
4463 4465
4464 __ bind(&stub_call); 4466 __ bind(&stub_call);
4465 __ mov(a1, v0); 4467 __ mov(a1, v0);
4466 __ li(a0, Operand(Smi::FromInt(count_value))); 4468 __ li(a0, Operand(Smi::FromInt(count_value)));
4467 4469
4468 // Record position before stub call. 4470 // Record position before stub call.
4469 SetSourcePosition(expr->position()); 4471 SetSourcePosition(expr->position());
4470 4472
4471 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); 4473 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
4472 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId()); 4474 CallIC(stub.GetCode(isolate()),
4475 NOT_CONTEXTUAL,
4476 expr->CountBinOpFeedbackId());
4473 patch_site.EmitPatchInfo(); 4477 patch_site.EmitPatchInfo();
4474 __ bind(&done); 4478 __ bind(&done);
4475 4479
4476 // Store the value returned in v0. 4480 // Store the value returned in v0.
4477 switch (assign_type) { 4481 switch (assign_type) {
4478 case VARIABLE: 4482 case VARIABLE:
4479 if (expr->is_postfix()) { 4483 if (expr->is_postfix()) {
4480 { EffectContext context(this); 4484 { EffectContext context(this);
4481 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4485 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4482 Token::ASSIGN); 4486 Token::ASSIGN);
4483 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4487 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4484 context.Plug(v0); 4488 context.Plug(v0);
4485 } 4489 }
4486 // For all contexts except EffectConstant we have the result on 4490 // For all contexts except EffectConstant we have the result on
4487 // top of the stack. 4491 // top of the stack.
4488 if (!context()->IsEffect()) { 4492 if (!context()->IsEffect()) {
4489 context()->PlugTOS(); 4493 context()->PlugTOS();
4490 } 4494 }
4491 } else { 4495 } else {
4492 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4496 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4493 Token::ASSIGN); 4497 Token::ASSIGN);
4494 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4498 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4495 context()->Plug(v0); 4499 context()->Plug(v0);
4496 } 4500 }
4497 break; 4501 break;
4498 case NAMED_PROPERTY: { 4502 case NAMED_PROPERTY: {
4499 __ mov(a0, result_register()); // Value. 4503 __ mov(a0, result_register()); // Value.
4500 __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name. 4504 __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name.
4501 __ pop(a1); // Receiver. 4505 __ pop(a1); // Receiver.
4502 CallStoreIC(expr->CountStoreFeedbackId()); 4506 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId());
4503 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4507 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4504 if (expr->is_postfix()) { 4508 if (expr->is_postfix()) {
4505 if (!context()->IsEffect()) { 4509 if (!context()->IsEffect()) {
4506 context()->PlugTOS(); 4510 context()->PlugTOS();
4507 } 4511 }
4508 } else { 4512 } else {
4509 context()->Plug(v0); 4513 context()->Plug(v0);
4510 } 4514 }
4511 break; 4515 break;
4512 } 4516 }
4513 case KEYED_PROPERTY: { 4517 case KEYED_PROPERTY: {
4514 __ mov(a0, result_register()); // Value. 4518 __ mov(a0, result_register()); // Value.
4515 __ Pop(a2, a1); // a1 = key, a2 = receiver. 4519 __ Pop(a2, a1); // a1 = key, a2 = receiver.
4516 Handle<Code> ic = is_classic_mode() 4520 Handle<Code> ic = is_classic_mode()
4517 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4521 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4518 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4522 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4519 CallIC(ic, expr->CountStoreFeedbackId()); 4523 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId());
4520 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4524 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4521 if (expr->is_postfix()) { 4525 if (expr->is_postfix()) {
4522 if (!context()->IsEffect()) { 4526 if (!context()->IsEffect()) {
4523 context()->PlugTOS(); 4527 context()->PlugTOS();
4524 } 4528 }
4525 } else { 4529 } else {
4526 context()->Plug(v0); 4530 context()->Plug(v0);
4527 } 4531 }
4528 break; 4532 break;
4529 } 4533 }
4530 } 4534 }
4531 } 4535 }
4532 4536
4533 4537
4534 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4538 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4535 ASSERT(!context()->IsEffect()); 4539 ASSERT(!context()->IsEffect());
4536 ASSERT(!context()->IsTest()); 4540 ASSERT(!context()->IsTest());
4537 VariableProxy* proxy = expr->AsVariableProxy(); 4541 VariableProxy* proxy = expr->AsVariableProxy();
4538 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4542 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4539 Comment cmnt(masm_, "[ Global variable"); 4543 Comment cmnt(masm_, "Global variable");
4540 __ lw(a0, GlobalObjectOperand()); 4544 __ lw(a0, GlobalObjectOperand());
4541 __ li(a2, Operand(proxy->name())); 4545 __ li(a2, Operand(proxy->name()));
4542 // Use a regular load, not a contextual load, to avoid a reference 4546 // Use a regular load, not a contextual load, to avoid a reference
4543 // error. 4547 // error.
4544 CallLoadIC(NOT_CONTEXTUAL); 4548 CallLoadIC(NOT_CONTEXTUAL);
4545 PrepareForBailout(expr, TOS_REG); 4549 PrepareForBailout(expr, TOS_REG);
4546 context()->Plug(v0); 4550 context()->Plug(v0);
4547 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4551 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4548 Comment cmnt(masm_, "[ Lookup slot");
4549 Label done, slow; 4552 Label done, slow;
4550 4553
4551 // Generate code for loading from variables potentially shadowed 4554 // Generate code for loading from variables potentially shadowed
4552 // by eval-introduced variables. 4555 // by eval-introduced variables.
4553 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); 4556 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done);
4554 4557
4555 __ bind(&slow); 4558 __ bind(&slow);
4556 __ li(a0, Operand(proxy->name())); 4559 __ li(a0, Operand(proxy->name()));
4557 __ Push(cp, a0); 4560 __ Push(cp, a0);
4558 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 4561 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
4695 if (inline_smi_code) { 4698 if (inline_smi_code) {
4696 Label slow_case; 4699 Label slow_case;
4697 __ Or(a2, a0, Operand(a1)); 4700 __ Or(a2, a0, Operand(a1));
4698 patch_site.EmitJumpIfNotSmi(a2, &slow_case); 4701 patch_site.EmitJumpIfNotSmi(a2, &slow_case);
4699 Split(cc, a1, Operand(a0), if_true, if_false, NULL); 4702 Split(cc, a1, Operand(a0), if_true, if_false, NULL);
4700 __ bind(&slow_case); 4703 __ bind(&slow_case);
4701 } 4704 }
4702 // Record position and call the compare IC. 4705 // Record position and call the compare IC.
4703 SetSourcePosition(expr->position()); 4706 SetSourcePosition(expr->position());
4704 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 4707 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
4705 CallIC(ic, expr->CompareOperationFeedbackId()); 4708 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId());
4706 patch_site.EmitPatchInfo(); 4709 patch_site.EmitPatchInfo();
4707 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4710 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4708 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); 4711 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through);
4709 } 4712 }
4710 } 4713 }
4711 4714
4712 // Convert the result of the comparison into one expected for this 4715 // Convert the result of the comparison into one expected for this
4713 // expression's context. 4716 // expression's context.
4714 context()->Plug(if_true, if_false); 4717 context()->Plug(if_true, if_false);
4715 } 4718 }
(...skipping 13 matching lines...) Expand all
4729 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4732 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4730 __ mov(a0, result_register()); 4733 __ mov(a0, result_register());
4731 if (expr->op() == Token::EQ_STRICT) { 4734 if (expr->op() == Token::EQ_STRICT) {
4732 Heap::RootListIndex nil_value = nil == kNullValue ? 4735 Heap::RootListIndex nil_value = nil == kNullValue ?
4733 Heap::kNullValueRootIndex : 4736 Heap::kNullValueRootIndex :
4734 Heap::kUndefinedValueRootIndex; 4737 Heap::kUndefinedValueRootIndex;
4735 __ LoadRoot(a1, nil_value); 4738 __ LoadRoot(a1, nil_value);
4736 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); 4739 Split(eq, a0, Operand(a1), if_true, if_false, fall_through);
4737 } else { 4740 } else {
4738 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4741 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
4739 CallIC(ic, expr->CompareOperationFeedbackId()); 4742 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId());
4740 Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through); 4743 Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through);
4741 } 4744 }
4742 context()->Plug(if_true, if_false); 4745 context()->Plug(if_true, if_false);
4743 } 4746 }
4744 4747
4745 4748
4746 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4749 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4747 __ lw(v0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4750 __ lw(v0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4748 context()->Plug(v0); 4751 context()->Plug(v0);
4749 } 4752 }
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
4967 Assembler::target_address_at(pc_immediate_load_address)) == 4970 Assembler::target_address_at(pc_immediate_load_address)) ==
4968 reinterpret_cast<uint32_t>( 4971 reinterpret_cast<uint32_t>(
4969 isolate->builtins()->OsrAfterStackCheck()->entry())); 4972 isolate->builtins()->OsrAfterStackCheck()->entry()));
4970 return OSR_AFTER_STACK_CHECK; 4973 return OSR_AFTER_STACK_CHECK;
4971 } 4974 }
4972 4975
4973 4976
4974 } } // namespace v8::internal 4977 } } // namespace v8::internal
4975 4978
4976 #endif // V8_TARGET_ARCH_MIPS 4979 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/debug-mips.cc ('k') | src/mips/ic-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698