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

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

Issue 159933002: A64: Synchronize with r19289. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/objects.h » ('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
141 profiling_counter_ = isolate()->factory()->NewCell( 144 profiling_counter_ = isolate()->factory()->NewCell(
142 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 145 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
143 SetFunctionPosition(function()); 146 SetFunctionPosition(function());
144 Comment cmnt(masm_, "[ function compiled by full code generator"); 147 Comment cmnt(masm_, "[ function compiled by full code generator");
145 148
146 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 149 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
147 150
148 #ifdef DEBUG 151 #ifdef DEBUG
149 if (strlen(FLAG_stop_at) > 0 && 152 if (strlen(FLAG_stop_at) > 0 &&
150 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 153 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 } 675 }
673 } 676 }
674 677
675 678
676 void FullCodeGenerator::DoTest(Expression* condition, 679 void FullCodeGenerator::DoTest(Expression* condition,
677 Label* if_true, 680 Label* if_true,
678 Label* if_false, 681 Label* if_false,
679 Label* fall_through) { 682 Label* fall_through) {
680 __ mov(a0, result_register()); 683 __ mov(a0, result_register());
681 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 684 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
682 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); 685 CallIC(ic, condition->test_id());
683 __ mov(at, zero_reg); 686 __ mov(at, zero_reg);
684 Split(ne, v0, Operand(at), if_true, if_false, fall_through); 687 Split(ne, v0, Operand(at), if_true, if_false, fall_through);
685 } 688 }
686 689
687 690
688 void FullCodeGenerator::Split(Condition cc, 691 void FullCodeGenerator::Split(Condition cc,
689 Register lhs, 692 Register lhs,
690 const Operand& rhs, 693 const Operand& rhs,
691 Label* if_true, 694 Label* if_true,
692 Label* if_false, 695 Label* if_false,
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 __ Branch(&next_test, ne, a1, Operand(a0)); 1040 __ Branch(&next_test, ne, a1, Operand(a0));
1038 __ Drop(1); // Switch value is no longer needed. 1041 __ Drop(1); // Switch value is no longer needed.
1039 __ Branch(clause->body_target()); 1042 __ Branch(clause->body_target());
1040 1043
1041 __ bind(&slow_case); 1044 __ bind(&slow_case);
1042 } 1045 }
1043 1046
1044 // Record position before stub call for type feedback. 1047 // Record position before stub call for type feedback.
1045 SetSourcePosition(clause->position()); 1048 SetSourcePosition(clause->position());
1046 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 1049 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
1047 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); 1050 CallIC(ic, clause->CompareId());
1048 patch_site.EmitPatchInfo(); 1051 patch_site.EmitPatchInfo();
1049 1052
1050 Label skip; 1053 Label skip;
1051 __ Branch(&skip); 1054 __ Branch(&skip);
1052 PrepareForBailout(clause, TOS_REG); 1055 PrepareForBailout(clause, TOS_REG);
1053 __ LoadRoot(at, Heap::kTrueValueRootIndex); 1056 __ LoadRoot(at, Heap::kTrueValueRootIndex);
1054 __ Branch(&next_test, ne, v0, Operand(at)); 1057 __ Branch(&next_test, ne, v0, Operand(at));
1055 __ Drop(1); 1058 __ Drop(1);
1056 __ Branch(clause->body_target()); 1059 __ Branch(clause->body_target());
1057 __ bind(&skip); 1060 __ bind(&skip);
(...skipping 22 matching lines...) Expand all
1080 VisitStatements(clause->statements()); 1083 VisitStatements(clause->statements());
1081 } 1084 }
1082 1085
1083 __ bind(nested_statement.break_label()); 1086 __ bind(nested_statement.break_label());
1084 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1087 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1085 } 1088 }
1086 1089
1087 1090
1088 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1091 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1089 Comment cmnt(masm_, "[ ForInStatement"); 1092 Comment cmnt(masm_, "[ ForInStatement");
1093 int slot = stmt->ForInFeedbackSlot();
1090 SetStatementPosition(stmt); 1094 SetStatementPosition(stmt);
1091 1095
1092 Label loop, exit; 1096 Label loop, exit;
1093 ForIn loop_statement(this, stmt); 1097 ForIn loop_statement(this, stmt);
1094 increment_loop_depth(); 1098 increment_loop_depth();
1095 1099
1096 // Get the object to enumerate over. If the object is null or undefined, skip 1100 // Get the object to enumerate over. If the object is null or undefined, skip
1097 // over the loop. See ECMA-262 version 5, section 12.6.4. 1101 // over the loop. See ECMA-262 version 5, section 12.6.4.
1098 VisitForAccumulatorValue(stmt->enumerable()); 1102 VisitForAccumulatorValue(stmt->enumerable());
1099 __ mov(a0, result_register()); // Result as param to InvokeBuiltin below. 1103 __ mov(a0, result_register()); // Result as param to InvokeBuiltin below.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 __ jmp(&loop); 1169 __ jmp(&loop);
1166 1170
1167 __ bind(&no_descriptors); 1171 __ bind(&no_descriptors);
1168 __ Drop(1); 1172 __ Drop(1);
1169 __ jmp(&exit); 1173 __ jmp(&exit);
1170 1174
1171 // We got a fixed array in register v0. Iterate through that. 1175 // We got a fixed array in register v0. Iterate through that.
1172 Label non_proxy; 1176 Label non_proxy;
1173 __ bind(&fixed_array); 1177 __ bind(&fixed_array);
1174 1178
1175 Handle<Cell> cell = isolate()->factory()->NewCell( 1179 Handle<Object> feedback = Handle<Object>(
1176 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), 1180 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
1177 isolate())); 1181 isolate());
1178 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); 1182 StoreFeedbackVectorSlot(slot, feedback);
1179 __ li(a1, cell); 1183 __ li(a1, FeedbackVector());
1180 __ li(a2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); 1184 __ li(a2, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
1181 __ sw(a2, FieldMemOperand(a1, Cell::kValueOffset)); 1185 __ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot)));
1182 1186
1183 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check 1187 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check
1184 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object 1188 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
1185 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1189 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1186 __ GetObjectType(a2, a3, a3); 1190 __ GetObjectType(a2, a3, a3);
1187 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE)); 1191 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE));
1188 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy 1192 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy
1189 __ bind(&non_proxy); 1193 __ bind(&non_proxy);
1190 __ Push(a1, v0); // Smi and array 1194 __ Push(a1, v0); // Smi and array
1191 __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); 1195 __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset));
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1700 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1697 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1701 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
1698 // Fall through. 1702 // Fall through.
1699 case ObjectLiteral::Property::COMPUTED: 1703 case ObjectLiteral::Property::COMPUTED:
1700 if (key->value()->IsInternalizedString()) { 1704 if (key->value()->IsInternalizedString()) {
1701 if (property->emit_store()) { 1705 if (property->emit_store()) {
1702 VisitForAccumulatorValue(value); 1706 VisitForAccumulatorValue(value);
1703 __ mov(a0, result_register()); 1707 __ mov(a0, result_register());
1704 __ li(a2, Operand(key->value())); 1708 __ li(a2, Operand(key->value()));
1705 __ lw(a1, MemOperand(sp)); 1709 __ lw(a1, MemOperand(sp));
1706 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); 1710 CallStoreIC(key->LiteralFeedbackId());
1707 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1711 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1708 } else { 1712 } else {
1709 VisitForEffect(value); 1713 VisitForEffect(value);
1710 } 1714 }
1711 break; 1715 break;
1712 } 1716 }
1713 // Duplicate receiver on stack. 1717 // Duplicate receiver on stack.
1714 __ lw(a0, MemOperand(sp)); 1718 __ lw(a0, MemOperand(sp));
1715 __ push(a0); 1719 __ push(a0);
1716 VisitForStackValue(key); 1720 VisitForStackValue(key);
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 __ bind(&l_next); 2108 __ bind(&l_next);
2105 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" 2109 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
2106 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2110 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
2107 __ Push(a2, a3, a0); // "next", iter, received 2111 __ Push(a2, a3, a0); // "next", iter, received
2108 2112
2109 // result = receiver[f](arg); 2113 // result = receiver[f](arg);
2110 __ bind(&l_call); 2114 __ bind(&l_call);
2111 __ lw(a1, MemOperand(sp, kPointerSize)); 2115 __ lw(a1, MemOperand(sp, kPointerSize));
2112 __ lw(a0, MemOperand(sp, 2 * kPointerSize)); 2116 __ lw(a0, MemOperand(sp, 2 * kPointerSize));
2113 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2117 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2114 CallIC(ic, NOT_CONTEXTUAL, TypeFeedbackId::None()); 2118 CallIC(ic, TypeFeedbackId::None());
2115 __ mov(a0, v0); 2119 __ mov(a0, v0);
2116 __ mov(a1, a0); 2120 __ mov(a1, a0);
2117 __ sw(a1, MemOperand(sp, 2 * kPointerSize)); 2121 __ sw(a1, MemOperand(sp, 2 * kPointerSize));
2118 CallFunctionStub stub(1, CALL_AS_METHOD); 2122 CallFunctionStub stub(1, CALL_AS_METHOD);
2119 __ CallStub(&stub); 2123 __ CallStub(&stub);
2120 2124
2121 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2125 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2122 __ Drop(1); // The function is still on the stack; drop it. 2126 __ Drop(1); // The function is still on the stack; drop it.
2123 2127
2124 // if (!result.done) goto l_try; 2128 // if (!result.done) goto l_try;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2302 // Call load IC. It has arguments receiver and property name a0 and a2. 2306 // Call load IC. It has arguments receiver and property name a0 and a2.
2303 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2307 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2304 } 2308 }
2305 2309
2306 2310
2307 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2311 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2308 SetSourcePosition(prop->position()); 2312 SetSourcePosition(prop->position());
2309 __ mov(a0, result_register()); 2313 __ mov(a0, result_register());
2310 // Call keyed load IC. It has arguments key and receiver in a0 and a1. 2314 // Call keyed load IC. It has arguments key and receiver in a0 and a1.
2311 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2315 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2312 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2316 CallIC(ic, prop->PropertyFeedbackId());
2313 } 2317 }
2314 2318
2315 2319
2316 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2320 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2317 Token::Value op, 2321 Token::Value op,
2318 OverwriteMode mode, 2322 OverwriteMode mode,
2319 Expression* left_expr, 2323 Expression* left_expr,
2320 Expression* right_expr) { 2324 Expression* right_expr) {
2321 Label done, smi_case, stub_call; 2325 Label done, smi_case, stub_call;
2322 2326
2323 Register scratch1 = a2; 2327 Register scratch1 = a2;
2324 Register scratch2 = a3; 2328 Register scratch2 = a3;
2325 2329
2326 // Get the arguments. 2330 // Get the arguments.
2327 Register left = a1; 2331 Register left = a1;
2328 Register right = a0; 2332 Register right = a0;
2329 __ pop(left); 2333 __ pop(left);
2330 __ mov(a0, result_register()); 2334 __ mov(a0, result_register());
2331 2335
2332 // Perform combined smi check on both operands. 2336 // Perform combined smi check on both operands.
2333 __ Or(scratch1, left, Operand(right)); 2337 __ Or(scratch1, left, Operand(right));
2334 STATIC_ASSERT(kSmiTag == 0); 2338 STATIC_ASSERT(kSmiTag == 0);
2335 JumpPatchSite patch_site(masm_); 2339 JumpPatchSite patch_site(masm_);
2336 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 2340 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2337 2341
2338 __ bind(&stub_call); 2342 __ bind(&stub_call);
2339 BinaryOpICStub stub(op, mode); 2343 BinaryOpICStub stub(op, mode);
2340 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2344 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2341 expr->BinaryOperationFeedbackId());
2342 patch_site.EmitPatchInfo(); 2345 patch_site.EmitPatchInfo();
2343 __ jmp(&done); 2346 __ jmp(&done);
2344 2347
2345 __ bind(&smi_case); 2348 __ bind(&smi_case);
2346 // Smi case. This code works the same way as the smi-smi case in the type 2349 // Smi case. This code works the same way as the smi-smi case in the type
2347 // recording binary operation stub, see 2350 // recording binary operation stub, see
2348 switch (op) { 2351 switch (op) {
2349 case Token::SAR: 2352 case Token::SAR:
2350 __ GetLeastBitsFromSmi(scratch1, right, 5); 2353 __ GetLeastBitsFromSmi(scratch1, right, 5);
2351 __ srav(right, left, scratch1); 2354 __ srav(right, left, scratch1);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 } 2413 }
2411 2414
2412 2415
2413 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 2416 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
2414 Token::Value op, 2417 Token::Value op,
2415 OverwriteMode mode) { 2418 OverwriteMode mode) {
2416 __ mov(a0, result_register()); 2419 __ mov(a0, result_register());
2417 __ pop(a1); 2420 __ pop(a1);
2418 BinaryOpICStub stub(op, mode); 2421 BinaryOpICStub stub(op, mode);
2419 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2422 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2420 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2423 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2421 expr->BinaryOperationFeedbackId());
2422 patch_site.EmitPatchInfo(); 2424 patch_site.EmitPatchInfo();
2423 context()->Plug(v0); 2425 context()->Plug(v0);
2424 } 2426 }
2425 2427
2426 2428
2427 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2429 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2428 // Invalid left-hand sides are rewritten by the parser to have a 'throw 2430 // Invalid left-hand sides are rewritten by the parser to have a 'throw
2429 // ReferenceError' on the left-hand side. 2431 // ReferenceError' on the left-hand side.
2430 if (!expr->IsValidLeftHandSide()) { 2432 if (!expr->IsValidLeftHandSide()) {
2431 VisitForEffect(expr); 2433 VisitForEffect(expr);
(...skipping 17 matching lines...) Expand all
2449 EffectContext context(this); 2451 EffectContext context(this);
2450 EmitVariableAssignment(var, Token::ASSIGN); 2452 EmitVariableAssignment(var, Token::ASSIGN);
2451 break; 2453 break;
2452 } 2454 }
2453 case NAMED_PROPERTY: { 2455 case NAMED_PROPERTY: {
2454 __ push(result_register()); // Preserve value. 2456 __ push(result_register()); // Preserve value.
2455 VisitForAccumulatorValue(prop->obj()); 2457 VisitForAccumulatorValue(prop->obj());
2456 __ mov(a1, result_register()); 2458 __ mov(a1, result_register());
2457 __ pop(a0); // Restore value. 2459 __ pop(a0); // Restore value.
2458 __ li(a2, Operand(prop->key()->AsLiteral()->value())); 2460 __ li(a2, Operand(prop->key()->AsLiteral()->value()));
2459 CallStoreIC(NOT_CONTEXTUAL); 2461 CallStoreIC();
2460 break; 2462 break;
2461 } 2463 }
2462 case KEYED_PROPERTY: { 2464 case KEYED_PROPERTY: {
2463 __ push(result_register()); // Preserve value. 2465 __ push(result_register()); // Preserve value.
2464 VisitForStackValue(prop->obj()); 2466 VisitForStackValue(prop->obj());
2465 VisitForAccumulatorValue(prop->key()); 2467 VisitForAccumulatorValue(prop->key());
2466 __ mov(a1, result_register()); 2468 __ mov(a1, result_register());
2467 __ Pop(a0, a2); // a0 = restored value. 2469 __ Pop(a0, a2); // a0 = restored value.
2468 Handle<Code> ic = is_classic_mode() 2470 Handle<Code> ic = is_classic_mode()
2469 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2471 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2470 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2472 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2471 CallIC(ic); 2473 CallIC(ic);
2472 break; 2474 break;
2473 } 2475 }
2474 } 2476 }
2475 context()->Plug(v0); 2477 context()->Plug(v0);
2476 } 2478 }
2477 2479
2478 2480
2479 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2481 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2480 Token::Value op) { 2482 Token::Value op) {
2481 if (var->IsUnallocated()) { 2483 if (var->IsUnallocated()) {
2482 // Global var, const, or let. 2484 // Global var, const, or let.
2483 __ mov(a0, result_register()); 2485 __ mov(a0, result_register());
2484 __ li(a2, Operand(var->name())); 2486 __ li(a2, Operand(var->name()));
2485 __ lw(a1, GlobalObjectOperand()); 2487 __ lw(a1, GlobalObjectOperand());
2486 CallStoreIC(CONTEXTUAL); 2488 CallStoreIC();
2487 } else if (op == Token::INIT_CONST) { 2489 } else if (op == Token::INIT_CONST) {
2488 // Const initializers need a write barrier. 2490 // Const initializers need a write barrier.
2489 ASSERT(!var->IsParameter()); // No const parameters. 2491 ASSERT(!var->IsParameter()); // No const parameters.
2490 if (var->IsStackLocal()) { 2492 if (var->IsStackLocal()) {
2491 Label skip; 2493 Label skip;
2492 __ lw(a1, StackOperand(var)); 2494 __ lw(a1, StackOperand(var));
2493 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2495 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
2494 __ Branch(&skip, ne, a1, Operand(t0)); 2496 __ Branch(&skip, ne, a1, Operand(t0));
2495 __ sw(result_register(), StackOperand(var)); 2497 __ sw(result_register(), StackOperand(var));
2496 __ bind(&skip); 2498 __ bind(&skip);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2571 Property* prop = expr->target()->AsProperty(); 2573 Property* prop = expr->target()->AsProperty();
2572 ASSERT(prop != NULL); 2574 ASSERT(prop != NULL);
2573 ASSERT(prop->key()->AsLiteral() != NULL); 2575 ASSERT(prop->key()->AsLiteral() != NULL);
2574 2576
2575 // Record source code position before IC call. 2577 // Record source code position before IC call.
2576 SetSourcePosition(expr->position()); 2578 SetSourcePosition(expr->position());
2577 __ mov(a0, result_register()); // Load the value. 2579 __ mov(a0, result_register()); // Load the value.
2578 __ li(a2, Operand(prop->key()->AsLiteral()->value())); 2580 __ li(a2, Operand(prop->key()->AsLiteral()->value()));
2579 __ pop(a1); 2581 __ pop(a1);
2580 2582
2581 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2583 CallStoreIC(expr->AssignmentFeedbackId());
2582 2584
2583 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2585 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2584 context()->Plug(v0); 2586 context()->Plug(v0);
2585 } 2587 }
2586 2588
2587 2589
2588 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2590 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2589 // Assignment to a property, using a keyed store IC. 2591 // Assignment to a property, using a keyed store IC.
2590 2592
2591 // Record source code position before IC call. 2593 // Record source code position before IC call.
2592 SetSourcePosition(expr->position()); 2594 SetSourcePosition(expr->position());
2593 // Call keyed store IC. 2595 // Call keyed store IC.
2594 // The arguments are: 2596 // The arguments are:
2595 // - a0 is the value, 2597 // - a0 is the value,
2596 // - a1 is the key, 2598 // - a1 is the key,
2597 // - a2 is the receiver. 2599 // - a2 is the receiver.
2598 __ mov(a0, result_register()); 2600 __ mov(a0, result_register());
2599 __ Pop(a2, a1); // a1 = key. 2601 __ Pop(a2, a1); // a1 = key.
2600 2602
2601 Handle<Code> ic = is_classic_mode() 2603 Handle<Code> ic = is_classic_mode()
2602 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2604 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2603 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2605 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2604 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2606 CallIC(ic, expr->AssignmentFeedbackId());
2605 2607
2606 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2608 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2607 context()->Plug(v0); 2609 context()->Plug(v0);
2608 } 2610 }
2609 2611
2610 2612
2611 void FullCodeGenerator::VisitProperty(Property* expr) { 2613 void FullCodeGenerator::VisitProperty(Property* expr) {
2612 Comment cmnt(masm_, "[ Property"); 2614 Comment cmnt(masm_, "[ Property");
2613 Expression* key = expr->key(); 2615 Expression* key = expr->key();
2614 2616
2615 if (key->IsPropertyName()) { 2617 if (key->IsPropertyName()) {
2616 VisitForAccumulatorValue(expr->obj()); 2618 VisitForAccumulatorValue(expr->obj());
2617 EmitNamedPropertyLoad(expr); 2619 EmitNamedPropertyLoad(expr);
2618 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2620 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2619 context()->Plug(v0); 2621 context()->Plug(v0);
2620 } else { 2622 } else {
2621 VisitForStackValue(expr->obj()); 2623 VisitForStackValue(expr->obj());
2622 VisitForAccumulatorValue(expr->key()); 2624 VisitForAccumulatorValue(expr->key());
2623 __ pop(a1); 2625 __ pop(a1);
2624 EmitKeyedPropertyLoad(expr); 2626 EmitKeyedPropertyLoad(expr);
2625 context()->Plug(v0); 2627 context()->Plug(v0);
2626 } 2628 }
2627 } 2629 }
2628 2630
2629 2631
2630 void FullCodeGenerator::CallIC(Handle<Code> code, 2632 void FullCodeGenerator::CallIC(Handle<Code> code,
2631 ContextualMode mode,
2632 TypeFeedbackId id) { 2633 TypeFeedbackId id) {
2633 ic_total_count_++; 2634 ic_total_count_++;
2634 ASSERT(mode != CONTEXTUAL || id.IsNone());
2635 __ Call(code, RelocInfo::CODE_TARGET, id); 2635 __ Call(code, RelocInfo::CODE_TARGET, id);
2636 } 2636 }
2637 2637
2638 2638
2639 // Code common for calls using the IC. 2639 // Code common for calls using the IC.
2640 void FullCodeGenerator::EmitCallWithIC(Call* expr) { 2640 void FullCodeGenerator::EmitCallWithIC(Call* expr) {
2641 Expression* callee = expr->expression(); 2641 Expression* callee = expr->expression();
2642 ZoneList<Expression*>* args = expr->arguments(); 2642 ZoneList<Expression*>* args = expr->arguments();
2643 int arg_count = args->length(); 2643 int arg_count = args->length();
2644 2644
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2734 int arg_count = args->length(); 2734 int arg_count = args->length();
2735 { PreservePositionScope scope(masm()->positions_recorder()); 2735 { PreservePositionScope scope(masm()->positions_recorder());
2736 for (int i = 0; i < arg_count; i++) { 2736 for (int i = 0; i < arg_count; i++) {
2737 VisitForStackValue(args->at(i)); 2737 VisitForStackValue(args->at(i));
2738 } 2738 }
2739 } 2739 }
2740 // Record source position for debugger. 2740 // Record source position for debugger.
2741 SetSourcePosition(expr->position()); 2741 SetSourcePosition(expr->position());
2742 2742
2743 Handle<Object> uninitialized = 2743 Handle<Object> uninitialized =
2744 TypeFeedbackCells::UninitializedSentinel(isolate()); 2744 TypeFeedbackInfo::UninitializedSentinel(isolate());
2745 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2745 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
2746 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); 2746 __ li(a2, FeedbackVector());
2747 __ li(a2, Operand(cell)); 2747 __ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
2748 2748
2749 // Record call targets in unoptimized code. 2749 // Record call targets in unoptimized code.
2750 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); 2750 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2751 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2751 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2752 __ CallStub(&stub, expr->CallFeedbackId()); 2752 __ CallStub(&stub);
2753 RecordJSReturnSite(expr); 2753 RecordJSReturnSite(expr);
2754 // Restore context register. 2754 // Restore context register.
2755 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2755 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2756 context()->DropAndPlug(1, v0); 2756 context()->DropAndPlug(1, v0);
2757 } 2757 }
2758 2758
2759 2759
2760 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2760 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2761 // 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.
2762 if (arg_count > 0) { 2762 if (arg_count > 0) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2921 // Call the construct call builtin that handles allocation and 2921 // Call the construct call builtin that handles allocation and
2922 // constructor invocation. 2922 // constructor invocation.
2923 SetSourcePosition(expr->position()); 2923 SetSourcePosition(expr->position());
2924 2924
2925 // Load function and argument count into a1 and a0. 2925 // Load function and argument count into a1 and a0.
2926 __ li(a0, Operand(arg_count)); 2926 __ li(a0, Operand(arg_count));
2927 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); 2927 __ lw(a1, MemOperand(sp, arg_count * kPointerSize));
2928 2928
2929 // Record call targets in unoptimized code. 2929 // Record call targets in unoptimized code.
2930 Handle<Object> uninitialized = 2930 Handle<Object> uninitialized =
2931 TypeFeedbackCells::UninitializedSentinel(isolate()); 2931 TypeFeedbackInfo::UninitializedSentinel(isolate());
2932 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2932 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
2933 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); 2933 __ li(a2, FeedbackVector());
2934 __ li(a2, Operand(cell)); 2934 __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
2935 2935
2936 CallConstructStub stub(RECORD_CALL_TARGET); 2936 CallConstructStub stub(RECORD_CALL_TARGET);
2937 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2937 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2938 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2938 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2939 context()->Plug(v0); 2939 context()->Plug(v0);
2940 } 2940 }
2941 2941
2942 2942
2943 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2943 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2944 ZoneList<Expression*>* args = expr->arguments(); 2944 ZoneList<Expression*>* args = expr->arguments();
(...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after
4464 } 4464 }
4465 4465
4466 __ bind(&stub_call); 4466 __ bind(&stub_call);
4467 __ mov(a1, v0); 4467 __ mov(a1, v0);
4468 __ li(a0, Operand(Smi::FromInt(count_value))); 4468 __ li(a0, Operand(Smi::FromInt(count_value)));
4469 4469
4470 // Record position before stub call. 4470 // Record position before stub call.
4471 SetSourcePosition(expr->position()); 4471 SetSourcePosition(expr->position());
4472 4472
4473 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); 4473 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
4474 CallIC(stub.GetCode(isolate()), 4474 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
4475 NOT_CONTEXTUAL,
4476 expr->CountBinOpFeedbackId());
4477 patch_site.EmitPatchInfo(); 4475 patch_site.EmitPatchInfo();
4478 __ bind(&done); 4476 __ bind(&done);
4479 4477
4480 // Store the value returned in v0. 4478 // Store the value returned in v0.
4481 switch (assign_type) { 4479 switch (assign_type) {
4482 case VARIABLE: 4480 case VARIABLE:
4483 if (expr->is_postfix()) { 4481 if (expr->is_postfix()) {
4484 { EffectContext context(this); 4482 { EffectContext context(this);
4485 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4483 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4486 Token::ASSIGN); 4484 Token::ASSIGN);
4487 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4485 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4488 context.Plug(v0); 4486 context.Plug(v0);
4489 } 4487 }
4490 // For all contexts except EffectConstant we have the result on 4488 // For all contexts except EffectConstant we have the result on
4491 // top of the stack. 4489 // top of the stack.
4492 if (!context()->IsEffect()) { 4490 if (!context()->IsEffect()) {
4493 context()->PlugTOS(); 4491 context()->PlugTOS();
4494 } 4492 }
4495 } else { 4493 } else {
4496 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4494 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4497 Token::ASSIGN); 4495 Token::ASSIGN);
4498 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4496 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4499 context()->Plug(v0); 4497 context()->Plug(v0);
4500 } 4498 }
4501 break; 4499 break;
4502 case NAMED_PROPERTY: { 4500 case NAMED_PROPERTY: {
4503 __ mov(a0, result_register()); // Value. 4501 __ mov(a0, result_register()); // Value.
4504 __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name. 4502 __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name.
4505 __ pop(a1); // Receiver. 4503 __ pop(a1); // Receiver.
4506 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4504 CallStoreIC(expr->CountStoreFeedbackId());
4507 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4505 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4508 if (expr->is_postfix()) { 4506 if (expr->is_postfix()) {
4509 if (!context()->IsEffect()) { 4507 if (!context()->IsEffect()) {
4510 context()->PlugTOS(); 4508 context()->PlugTOS();
4511 } 4509 }
4512 } else { 4510 } else {
4513 context()->Plug(v0); 4511 context()->Plug(v0);
4514 } 4512 }
4515 break; 4513 break;
4516 } 4514 }
4517 case KEYED_PROPERTY: { 4515 case KEYED_PROPERTY: {
4518 __ mov(a0, result_register()); // Value. 4516 __ mov(a0, result_register()); // Value.
4519 __ Pop(a2, a1); // a1 = key, a2 = receiver. 4517 __ Pop(a2, a1); // a1 = key, a2 = receiver.
4520 Handle<Code> ic = is_classic_mode() 4518 Handle<Code> ic = is_classic_mode()
4521 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4519 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4522 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4520 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4523 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4521 CallIC(ic, expr->CountStoreFeedbackId());
4524 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4522 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4525 if (expr->is_postfix()) { 4523 if (expr->is_postfix()) {
4526 if (!context()->IsEffect()) { 4524 if (!context()->IsEffect()) {
4527 context()->PlugTOS(); 4525 context()->PlugTOS();
4528 } 4526 }
4529 } else { 4527 } else {
4530 context()->Plug(v0); 4528 context()->Plug(v0);
4531 } 4529 }
4532 break; 4530 break;
4533 } 4531 }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
4698 if (inline_smi_code) { 4696 if (inline_smi_code) {
4699 Label slow_case; 4697 Label slow_case;
4700 __ Or(a2, a0, Operand(a1)); 4698 __ Or(a2, a0, Operand(a1));
4701 patch_site.EmitJumpIfNotSmi(a2, &slow_case); 4699 patch_site.EmitJumpIfNotSmi(a2, &slow_case);
4702 Split(cc, a1, Operand(a0), if_true, if_false, NULL); 4700 Split(cc, a1, Operand(a0), if_true, if_false, NULL);
4703 __ bind(&slow_case); 4701 __ bind(&slow_case);
4704 } 4702 }
4705 // Record position and call the compare IC. 4703 // Record position and call the compare IC.
4706 SetSourcePosition(expr->position()); 4704 SetSourcePosition(expr->position());
4707 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 4705 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
4708 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4706 CallIC(ic, expr->CompareOperationFeedbackId());
4709 patch_site.EmitPatchInfo(); 4707 patch_site.EmitPatchInfo();
4710 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4708 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4711 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); 4709 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through);
4712 } 4710 }
4713 } 4711 }
4714 4712
4715 // Convert the result of the comparison into one expected for this 4713 // Convert the result of the comparison into one expected for this
4716 // expression's context. 4714 // expression's context.
4717 context()->Plug(if_true, if_false); 4715 context()->Plug(if_true, if_false);
4718 } 4716 }
(...skipping 13 matching lines...) Expand all
4732 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4730 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4733 __ mov(a0, result_register()); 4731 __ mov(a0, result_register());
4734 if (expr->op() == Token::EQ_STRICT) { 4732 if (expr->op() == Token::EQ_STRICT) {
4735 Heap::RootListIndex nil_value = nil == kNullValue ? 4733 Heap::RootListIndex nil_value = nil == kNullValue ?
4736 Heap::kNullValueRootIndex : 4734 Heap::kNullValueRootIndex :
4737 Heap::kUndefinedValueRootIndex; 4735 Heap::kUndefinedValueRootIndex;
4738 __ LoadRoot(a1, nil_value); 4736 __ LoadRoot(a1, nil_value);
4739 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); 4737 Split(eq, a0, Operand(a1), if_true, if_false, fall_through);
4740 } else { 4738 } else {
4741 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4739 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
4742 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4740 CallIC(ic, expr->CompareOperationFeedbackId());
4743 Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through); 4741 Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through);
4744 } 4742 }
4745 context()->Plug(if_true, if_false); 4743 context()->Plug(if_true, if_false);
4746 } 4744 }
4747 4745
4748 4746
4749 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4747 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4750 __ lw(v0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4748 __ lw(v0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4751 context()->Plug(v0); 4749 context()->Plug(v0);
4752 } 4750 }
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
4970 Assembler::target_address_at(pc_immediate_load_address)) == 4968 Assembler::target_address_at(pc_immediate_load_address)) ==
4971 reinterpret_cast<uint32_t>( 4969 reinterpret_cast<uint32_t>(
4972 isolate->builtins()->OsrAfterStackCheck()->entry())); 4970 isolate->builtins()->OsrAfterStackCheck()->entry()));
4973 return OSR_AFTER_STACK_CHECK; 4971 return OSR_AFTER_STACK_CHECK;
4974 } 4972 }
4975 4973
4976 4974
4977 } } // namespace v8::internal 4975 } } // namespace v8::internal
4978 4976
4979 #endif // V8_TARGET_ARCH_MIPS 4977 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/debug-mips.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698