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

Side by Side Diff: src/arm/full-codegen-arm.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/arm/debug-arm.cc ('k') | src/ast.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 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 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 if (false_label_ != fall_through_) __ b(false_label_); 664 if (false_label_ != fall_through_) __ b(false_label_);
662 } 665 }
663 } 666 }
664 667
665 668
666 void FullCodeGenerator::DoTest(Expression* condition, 669 void FullCodeGenerator::DoTest(Expression* condition,
667 Label* if_true, 670 Label* if_true,
668 Label* if_false, 671 Label* if_false,
669 Label* fall_through) { 672 Label* fall_through) {
670 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 673 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
671 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); 674 CallIC(ic, condition->test_id());
672 __ tst(result_register(), result_register()); 675 __ tst(result_register(), result_register());
673 Split(ne, if_true, if_false, fall_through); 676 Split(ne, if_true, if_false, fall_through);
674 } 677 }
675 678
676 679
677 void FullCodeGenerator::Split(Condition cond, 680 void FullCodeGenerator::Split(Condition cond,
678 Label* if_true, 681 Label* if_true,
679 Label* if_false, 682 Label* if_false,
680 Label* fall_through) { 683 Label* fall_through) {
681 if (if_false == fall_through) { 684 if (if_false == fall_through) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 __ cmp(r1, r0); 1025 __ cmp(r1, r0);
1023 __ b(ne, &next_test); 1026 __ b(ne, &next_test);
1024 __ Drop(1); // Switch value is no longer needed. 1027 __ Drop(1); // Switch value is no longer needed.
1025 __ b(clause->body_target()); 1028 __ b(clause->body_target());
1026 __ bind(&slow_case); 1029 __ bind(&slow_case);
1027 } 1030 }
1028 1031
1029 // Record position before stub call for type feedback. 1032 // Record position before stub call for type feedback.
1030 SetSourcePosition(clause->position()); 1033 SetSourcePosition(clause->position());
1031 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 1034 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
1032 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); 1035 CallIC(ic, clause->CompareId());
1033 patch_site.EmitPatchInfo(); 1036 patch_site.EmitPatchInfo();
1034 1037
1035 Label skip; 1038 Label skip;
1036 __ b(&skip); 1039 __ b(&skip);
1037 PrepareForBailout(clause, TOS_REG); 1040 PrepareForBailout(clause, TOS_REG);
1038 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 1041 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
1039 __ cmp(r0, ip); 1042 __ cmp(r0, ip);
1040 __ b(ne, &next_test); 1043 __ b(ne, &next_test);
1041 __ Drop(1); 1044 __ Drop(1);
1042 __ jmp(clause->body_target()); 1045 __ jmp(clause->body_target());
(...skipping 24 matching lines...) Expand all
1067 VisitStatements(clause->statements()); 1070 VisitStatements(clause->statements());
1068 } 1071 }
1069 1072
1070 __ bind(nested_statement.break_label()); 1073 __ bind(nested_statement.break_label());
1071 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1074 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1072 } 1075 }
1073 1076
1074 1077
1075 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1078 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1076 Comment cmnt(masm_, "[ ForInStatement"); 1079 Comment cmnt(masm_, "[ ForInStatement");
1080 int slot = stmt->ForInFeedbackSlot();
1077 SetStatementPosition(stmt); 1081 SetStatementPosition(stmt);
1078 1082
1079 Label loop, exit; 1083 Label loop, exit;
1080 ForIn loop_statement(this, stmt); 1084 ForIn loop_statement(this, stmt);
1081 increment_loop_depth(); 1085 increment_loop_depth();
1082 1086
1083 // 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
1084 // 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.
1085 VisitForAccumulatorValue(stmt->enumerable()); 1089 VisitForAccumulatorValue(stmt->enumerable());
1086 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1090 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 __ jmp(&loop); 1160 __ jmp(&loop);
1157 1161
1158 __ bind(&no_descriptors); 1162 __ bind(&no_descriptors);
1159 __ Drop(1); 1163 __ Drop(1);
1160 __ jmp(&exit); 1164 __ jmp(&exit);
1161 1165
1162 // We got a fixed array in register r0. Iterate through that. 1166 // We got a fixed array in register r0. Iterate through that.
1163 Label non_proxy; 1167 Label non_proxy;
1164 __ bind(&fixed_array); 1168 __ bind(&fixed_array);
1165 1169
1166 Handle<Cell> cell = isolate()->factory()->NewCell( 1170 Handle<Object> feedback = Handle<Object>(
1167 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), 1171 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
1168 isolate())); 1172 isolate());
1169 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); 1173 StoreFeedbackVectorSlot(slot, feedback);
1170 __ Move(r1, cell); 1174 __ Move(r1, FeedbackVector());
1171 __ mov(r2, Operand(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); 1175 __ mov(r2, Operand(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
1172 __ str(r2, FieldMemOperand(r1, Cell::kValueOffset)); 1176 __ str(r2, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(slot)));
1173 1177
1174 __ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check 1178 __ mov(r1, Operand(Smi::FromInt(1))); // Smi indicates slow check
1175 __ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object 1179 __ ldr(r2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object
1176 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1180 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1177 __ CompareObjectType(r2, r3, r3, LAST_JS_PROXY_TYPE); 1181 __ CompareObjectType(r2, r3, r3, LAST_JS_PROXY_TYPE);
1178 __ b(gt, &non_proxy); 1182 __ b(gt, &non_proxy);
1179 __ mov(r1, Operand(Smi::FromInt(0))); // Zero indicates proxy 1183 __ mov(r1, Operand(Smi::FromInt(0))); // Zero indicates proxy
1180 __ bind(&non_proxy); 1184 __ bind(&non_proxy);
1181 __ Push(r1, r0); // Smi and array 1185 __ Push(r1, r0); // Smi and array
1182 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset)); 1186 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset));
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 UNREACHABLE(); 1689 UNREACHABLE();
1686 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1690 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1687 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1691 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
1688 // Fall through. 1692 // Fall through.
1689 case ObjectLiteral::Property::COMPUTED: 1693 case ObjectLiteral::Property::COMPUTED:
1690 if (key->value()->IsInternalizedString()) { 1694 if (key->value()->IsInternalizedString()) {
1691 if (property->emit_store()) { 1695 if (property->emit_store()) {
1692 VisitForAccumulatorValue(value); 1696 VisitForAccumulatorValue(value);
1693 __ mov(r2, Operand(key->value())); 1697 __ mov(r2, Operand(key->value()));
1694 __ ldr(r1, MemOperand(sp)); 1698 __ ldr(r1, MemOperand(sp));
1695 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); 1699 CallStoreIC(key->LiteralFeedbackId());
1696 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1700 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1697 } else { 1701 } else {
1698 VisitForEffect(value); 1702 VisitForEffect(value);
1699 } 1703 }
1700 break; 1704 break;
1701 } 1705 }
1702 // Duplicate receiver on stack. 1706 // Duplicate receiver on stack.
1703 __ ldr(r0, MemOperand(sp)); 1707 __ ldr(r0, MemOperand(sp));
1704 __ push(r0); 1708 __ push(r0);
1705 VisitForStackValue(key); 1709 VisitForStackValue(key);
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
2087 __ bind(&l_next); 2091 __ bind(&l_next);
2088 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" 2092 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next"
2089 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2093 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2090 __ Push(r2, r3, r0); // "next", iter, received 2094 __ Push(r2, r3, r0); // "next", iter, received
2091 2095
2092 // result = receiver[f](arg); 2096 // result = receiver[f](arg);
2093 __ bind(&l_call); 2097 __ bind(&l_call);
2094 __ ldr(r1, MemOperand(sp, kPointerSize)); 2098 __ ldr(r1, MemOperand(sp, kPointerSize));
2095 __ ldr(r0, MemOperand(sp, 2 * kPointerSize)); 2099 __ ldr(r0, MemOperand(sp, 2 * kPointerSize));
2096 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2100 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2097 CallIC(ic, NOT_CONTEXTUAL, TypeFeedbackId::None()); 2101 CallIC(ic, TypeFeedbackId::None());
2098 __ mov(r1, r0); 2102 __ mov(r1, r0);
2099 __ str(r1, MemOperand(sp, 2 * kPointerSize)); 2103 __ str(r1, MemOperand(sp, 2 * kPointerSize));
2100 CallFunctionStub stub(1, CALL_AS_METHOD); 2104 CallFunctionStub stub(1, CALL_AS_METHOD);
2101 __ CallStub(&stub); 2105 __ CallStub(&stub);
2102 2106
2103 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2107 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2104 __ Drop(1); // The function is still on the stack; drop it. 2108 __ Drop(1); // The function is still on the stack; drop it.
2105 2109
2106 // if (!result.done) goto l_try; 2110 // if (!result.done) goto l_try;
2107 __ bind(&l_loop); 2111 __ bind(&l_loop);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
2284 __ mov(r2, Operand(key->value())); 2288 __ mov(r2, Operand(key->value()));
2285 // Call load IC. It has arguments receiver and property name r0 and r2. 2289 // Call load IC. It has arguments receiver and property name r0 and r2.
2286 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2290 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2287 } 2291 }
2288 2292
2289 2293
2290 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2294 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2291 SetSourcePosition(prop->position()); 2295 SetSourcePosition(prop->position());
2292 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 2296 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
2293 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2297 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2294 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2298 CallIC(ic, prop->PropertyFeedbackId());
2295 } 2299 }
2296 2300
2297 2301
2298 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2302 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2299 Token::Value op, 2303 Token::Value op,
2300 OverwriteMode mode, 2304 OverwriteMode mode,
2301 Expression* left_expr, 2305 Expression* left_expr,
2302 Expression* right_expr) { 2306 Expression* right_expr) {
2303 Label done, smi_case, stub_call; 2307 Label done, smi_case, stub_call;
2304 2308
2305 Register scratch1 = r2; 2309 Register scratch1 = r2;
2306 Register scratch2 = r3; 2310 Register scratch2 = r3;
2307 2311
2308 // Get the arguments. 2312 // Get the arguments.
2309 Register left = r1; 2313 Register left = r1;
2310 Register right = r0; 2314 Register right = r0;
2311 __ pop(left); 2315 __ pop(left);
2312 2316
2313 // Perform combined smi check on both operands. 2317 // Perform combined smi check on both operands.
2314 __ orr(scratch1, left, Operand(right)); 2318 __ orr(scratch1, left, Operand(right));
2315 STATIC_ASSERT(kSmiTag == 0); 2319 STATIC_ASSERT(kSmiTag == 0);
2316 JumpPatchSite patch_site(masm_); 2320 JumpPatchSite patch_site(masm_);
2317 patch_site.EmitJumpIfSmi(scratch1, &smi_case); 2321 patch_site.EmitJumpIfSmi(scratch1, &smi_case);
2318 2322
2319 __ bind(&stub_call); 2323 __ bind(&stub_call);
2320 BinaryOpICStub stub(op, mode); 2324 BinaryOpICStub stub(op, mode);
2321 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2325 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2322 expr->BinaryOperationFeedbackId());
2323 patch_site.EmitPatchInfo(); 2326 patch_site.EmitPatchInfo();
2324 __ jmp(&done); 2327 __ jmp(&done);
2325 2328
2326 __ bind(&smi_case); 2329 __ bind(&smi_case);
2327 // Smi case. This code works the same way as the smi-smi case in the type 2330 // Smi case. This code works the same way as the smi-smi case in the type
2328 // recording binary operation stub, see 2331 // recording binary operation stub, see
2329 switch (op) { 2332 switch (op) {
2330 case Token::SAR: 2333 case Token::SAR:
2331 __ GetLeastBitsFromSmi(scratch1, right, 5); 2334 __ GetLeastBitsFromSmi(scratch1, right, 5);
2332 __ mov(right, Operand(left, ASR, scratch1)); 2335 __ mov(right, Operand(left, ASR, scratch1));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2389 context()->Plug(r0); 2392 context()->Plug(r0);
2390 } 2393 }
2391 2394
2392 2395
2393 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 2396 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
2394 Token::Value op, 2397 Token::Value op,
2395 OverwriteMode mode) { 2398 OverwriteMode mode) {
2396 __ pop(r1); 2399 __ pop(r1);
2397 BinaryOpICStub stub(op, mode); 2400 BinaryOpICStub stub(op, mode);
2398 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2401 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2399 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2402 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2400 expr->BinaryOperationFeedbackId());
2401 patch_site.EmitPatchInfo(); 2403 patch_site.EmitPatchInfo();
2402 context()->Plug(r0); 2404 context()->Plug(r0);
2403 } 2405 }
2404 2406
2405 2407
2406 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2408 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2407 // Invalid left-hand sides are rewritten by the parser to have a 'throw 2409 // Invalid left-hand sides are rewritten by the parser to have a 'throw
2408 // ReferenceError' on the left-hand side. 2410 // ReferenceError' on the left-hand side.
2409 if (!expr->IsValidLeftHandSide()) { 2411 if (!expr->IsValidLeftHandSide()) {
2410 VisitForEffect(expr); 2412 VisitForEffect(expr);
(...skipping 17 matching lines...) Expand all
2428 EffectContext context(this); 2430 EffectContext context(this);
2429 EmitVariableAssignment(var, Token::ASSIGN); 2431 EmitVariableAssignment(var, Token::ASSIGN);
2430 break; 2432 break;
2431 } 2433 }
2432 case NAMED_PROPERTY: { 2434 case NAMED_PROPERTY: {
2433 __ push(r0); // Preserve value. 2435 __ push(r0); // Preserve value.
2434 VisitForAccumulatorValue(prop->obj()); 2436 VisitForAccumulatorValue(prop->obj());
2435 __ mov(r1, r0); 2437 __ mov(r1, r0);
2436 __ pop(r0); // Restore value. 2438 __ pop(r0); // Restore value.
2437 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); 2439 __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
2438 CallStoreIC(NOT_CONTEXTUAL); 2440 CallStoreIC();
2439 break; 2441 break;
2440 } 2442 }
2441 case KEYED_PROPERTY: { 2443 case KEYED_PROPERTY: {
2442 __ push(r0); // Preserve value. 2444 __ push(r0); // Preserve value.
2443 VisitForStackValue(prop->obj()); 2445 VisitForStackValue(prop->obj());
2444 VisitForAccumulatorValue(prop->key()); 2446 VisitForAccumulatorValue(prop->key());
2445 __ mov(r1, r0); 2447 __ mov(r1, r0);
2446 __ Pop(r0, r2); // r0 = restored value. 2448 __ Pop(r0, r2); // r0 = restored value.
2447 Handle<Code> ic = is_classic_mode() 2449 Handle<Code> ic = is_classic_mode()
2448 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2450 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2449 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2451 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2450 CallIC(ic); 2452 CallIC(ic);
2451 break; 2453 break;
2452 } 2454 }
2453 } 2455 }
2454 context()->Plug(r0); 2456 context()->Plug(r0);
2455 } 2457 }
2456 2458
2457 2459
2458 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2460 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2459 Token::Value op) { 2461 Token::Value op) {
2460 if (var->IsUnallocated()) { 2462 if (var->IsUnallocated()) {
2461 // Global var, const, or let. 2463 // Global var, const, or let.
2462 __ mov(r2, Operand(var->name())); 2464 __ mov(r2, Operand(var->name()));
2463 __ ldr(r1, GlobalObjectOperand()); 2465 __ ldr(r1, GlobalObjectOperand());
2464 CallStoreIC(CONTEXTUAL); 2466 CallStoreIC();
2465 } else if (op == Token::INIT_CONST) { 2467 } else if (op == Token::INIT_CONST) {
2466 // Const initializers need a write barrier. 2468 // Const initializers need a write barrier.
2467 ASSERT(!var->IsParameter()); // No const parameters. 2469 ASSERT(!var->IsParameter()); // No const parameters.
2468 if (var->IsStackLocal()) { 2470 if (var->IsStackLocal()) {
2469 __ ldr(r1, StackOperand(var)); 2471 __ ldr(r1, StackOperand(var));
2470 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); 2472 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
2471 __ str(result_register(), StackOperand(var), eq); 2473 __ str(result_register(), StackOperand(var), eq);
2472 } else { 2474 } else {
2473 ASSERT(var->IsContextSlot() || var->IsLookupSlot()); 2475 ASSERT(var->IsContextSlot() || var->IsLookupSlot());
2474 // Like var declarations, const declarations are hoisted to function 2476 // Like var declarations, const declarations are hoisted to function
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2548 // Assignment to a property, using a named store IC. 2550 // Assignment to a property, using a named store IC.
2549 Property* prop = expr->target()->AsProperty(); 2551 Property* prop = expr->target()->AsProperty();
2550 ASSERT(prop != NULL); 2552 ASSERT(prop != NULL);
2551 ASSERT(prop->key()->AsLiteral() != NULL); 2553 ASSERT(prop->key()->AsLiteral() != NULL);
2552 2554
2553 // Record source code position before IC call. 2555 // Record source code position before IC call.
2554 SetSourcePosition(expr->position()); 2556 SetSourcePosition(expr->position());
2555 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); 2557 __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
2556 __ pop(r1); 2558 __ pop(r1);
2557 2559
2558 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2560 CallStoreIC(expr->AssignmentFeedbackId());
2559 2561
2560 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2562 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2561 context()->Plug(r0); 2563 context()->Plug(r0);
2562 } 2564 }
2563 2565
2564 2566
2565 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2567 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2566 // Assignment to a property, using a keyed store IC. 2568 // Assignment to a property, using a keyed store IC.
2567 2569
2568 // Record source code position before IC call. 2570 // Record source code position before IC call.
2569 SetSourcePosition(expr->position()); 2571 SetSourcePosition(expr->position());
2570 __ Pop(r2, r1); // r1 = key. 2572 __ Pop(r2, r1); // r1 = key.
2571 2573
2572 Handle<Code> ic = is_classic_mode() 2574 Handle<Code> ic = is_classic_mode()
2573 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2575 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2574 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2576 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2575 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2577 CallIC(ic, expr->AssignmentFeedbackId());
2576 2578
2577 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2579 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2578 context()->Plug(r0); 2580 context()->Plug(r0);
2579 } 2581 }
2580 2582
2581 2583
2582 void FullCodeGenerator::VisitProperty(Property* expr) { 2584 void FullCodeGenerator::VisitProperty(Property* expr) {
2583 Comment cmnt(masm_, "[ Property"); 2585 Comment cmnt(masm_, "[ Property");
2584 Expression* key = expr->key(); 2586 Expression* key = expr->key();
2585 2587
2586 if (key->IsPropertyName()) { 2588 if (key->IsPropertyName()) {
2587 VisitForAccumulatorValue(expr->obj()); 2589 VisitForAccumulatorValue(expr->obj());
2588 EmitNamedPropertyLoad(expr); 2590 EmitNamedPropertyLoad(expr);
2589 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2591 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2590 context()->Plug(r0); 2592 context()->Plug(r0);
2591 } else { 2593 } else {
2592 VisitForStackValue(expr->obj()); 2594 VisitForStackValue(expr->obj());
2593 VisitForAccumulatorValue(expr->key()); 2595 VisitForAccumulatorValue(expr->key());
2594 __ pop(r1); 2596 __ pop(r1);
2595 EmitKeyedPropertyLoad(expr); 2597 EmitKeyedPropertyLoad(expr);
2596 context()->Plug(r0); 2598 context()->Plug(r0);
2597 } 2599 }
2598 } 2600 }
2599 2601
2600 2602
2601 void FullCodeGenerator::CallIC(Handle<Code> code, 2603 void FullCodeGenerator::CallIC(Handle<Code> code,
2602 ContextualMode mode,
2603 TypeFeedbackId ast_id) { 2604 TypeFeedbackId ast_id) {
2604 ic_total_count_++; 2605 ic_total_count_++;
2605 // 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
2606 // the debugger can patch them correctly. 2607 // the debugger can patch them correctly.
2607 ASSERT(mode != CONTEXTUAL || ast_id.IsNone());
2608 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, 2608 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al,
2609 NEVER_INLINE_TARGET_ADDRESS); 2609 NEVER_INLINE_TARGET_ADDRESS);
2610 } 2610 }
2611 2611
2612 2612
2613 // Code common for calls using the IC. 2613 // Code common for calls using the IC.
2614 void FullCodeGenerator::EmitCallWithIC(Call* expr) { 2614 void FullCodeGenerator::EmitCallWithIC(Call* expr) {
2615 Expression* callee = expr->expression(); 2615 Expression* callee = expr->expression();
2616 ZoneList<Expression*>* args = expr->arguments(); 2616 ZoneList<Expression*>* args = expr->arguments();
2617 int arg_count = args->length(); 2617 int arg_count = args->length();
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2709 int arg_count = args->length(); 2709 int arg_count = args->length();
2710 { PreservePositionScope scope(masm()->positions_recorder()); 2710 { PreservePositionScope scope(masm()->positions_recorder());
2711 for (int i = 0; i < arg_count; i++) { 2711 for (int i = 0; i < arg_count; i++) {
2712 VisitForStackValue(args->at(i)); 2712 VisitForStackValue(args->at(i));
2713 } 2713 }
2714 } 2714 }
2715 // Record source position for debugger. 2715 // Record source position for debugger.
2716 SetSourcePosition(expr->position()); 2716 SetSourcePosition(expr->position());
2717 2717
2718 Handle<Object> uninitialized = 2718 Handle<Object> uninitialized =
2719 TypeFeedbackCells::UninitializedSentinel(isolate()); 2719 TypeFeedbackInfo::UninitializedSentinel(isolate());
2720 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2720 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
2721 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); 2721 __ Move(r2, FeedbackVector());
2722 __ mov(r2, Operand(cell)); 2722 __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
2723 2723
2724 // Record call targets in unoptimized code. 2724 // Record call targets in unoptimized code.
2725 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); 2725 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2726 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2726 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2727 __ CallStub(&stub, expr->CallFeedbackId()); 2727 __ CallStub(&stub);
2728 RecordJSReturnSite(expr); 2728 RecordJSReturnSite(expr);
2729 // Restore context register. 2729 // Restore context register.
2730 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2730 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2731 context()->DropAndPlug(1, r0); 2731 context()->DropAndPlug(1, r0);
2732 } 2732 }
2733 2733
2734 2734
2735 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2735 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2736 // 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.
2737 if (arg_count > 0) { 2737 if (arg_count > 0) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2898 // Call the construct call builtin that handles allocation and 2898 // Call the construct call builtin that handles allocation and
2899 // constructor invocation. 2899 // constructor invocation.
2900 SetSourcePosition(expr->position()); 2900 SetSourcePosition(expr->position());
2901 2901
2902 // Load function and argument count into r1 and r0. 2902 // Load function and argument count into r1 and r0.
2903 __ mov(r0, Operand(arg_count)); 2903 __ mov(r0, Operand(arg_count));
2904 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2904 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2905 2905
2906 // Record call targets in unoptimized code. 2906 // Record call targets in unoptimized code.
2907 Handle<Object> uninitialized = 2907 Handle<Object> uninitialized =
2908 TypeFeedbackCells::UninitializedSentinel(isolate()); 2908 TypeFeedbackInfo::UninitializedSentinel(isolate());
2909 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2909 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
2910 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); 2910 __ Move(r2, FeedbackVector());
2911 __ mov(r2, Operand(cell)); 2911 __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
2912 2912
2913 CallConstructStub stub(RECORD_CALL_TARGET); 2913 CallConstructStub stub(RECORD_CALL_TARGET);
2914 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2914 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2915 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2915 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2916 context()->Plug(r0); 2916 context()->Plug(r0);
2917 } 2917 }
2918 2918
2919 2919
2920 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2920 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2921 ZoneList<Expression*>* args = expr->arguments(); 2921 ZoneList<Expression*>* args = expr->arguments();
(...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after
4404 4404
4405 4405
4406 __ bind(&stub_call); 4406 __ bind(&stub_call);
4407 __ mov(r1, r0); 4407 __ mov(r1, r0);
4408 __ mov(r0, Operand(Smi::FromInt(count_value))); 4408 __ mov(r0, Operand(Smi::FromInt(count_value)));
4409 4409
4410 // Record position before stub call. 4410 // Record position before stub call.
4411 SetSourcePosition(expr->position()); 4411 SetSourcePosition(expr->position());
4412 4412
4413 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); 4413 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
4414 CallIC(stub.GetCode(isolate()), 4414 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
4415 NOT_CONTEXTUAL,
4416 expr->CountBinOpFeedbackId());
4417 patch_site.EmitPatchInfo(); 4415 patch_site.EmitPatchInfo();
4418 __ bind(&done); 4416 __ bind(&done);
4419 4417
4420 // Store the value returned in r0. 4418 // Store the value returned in r0.
4421 switch (assign_type) { 4419 switch (assign_type) {
4422 case VARIABLE: 4420 case VARIABLE:
4423 if (expr->is_postfix()) { 4421 if (expr->is_postfix()) {
4424 { EffectContext context(this); 4422 { EffectContext context(this);
4425 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4423 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4426 Token::ASSIGN); 4424 Token::ASSIGN);
4427 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4425 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4428 context.Plug(r0); 4426 context.Plug(r0);
4429 } 4427 }
4430 // For all contexts except EffectConstant We have the result on 4428 // For all contexts except EffectConstant We have the result on
4431 // top of the stack. 4429 // top of the stack.
4432 if (!context()->IsEffect()) { 4430 if (!context()->IsEffect()) {
4433 context()->PlugTOS(); 4431 context()->PlugTOS();
4434 } 4432 }
4435 } else { 4433 } else {
4436 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4434 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4437 Token::ASSIGN); 4435 Token::ASSIGN);
4438 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4436 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4439 context()->Plug(r0); 4437 context()->Plug(r0);
4440 } 4438 }
4441 break; 4439 break;
4442 case NAMED_PROPERTY: { 4440 case NAMED_PROPERTY: {
4443 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); 4441 __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
4444 __ pop(r1); 4442 __ pop(r1);
4445 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4443 CallStoreIC(expr->CountStoreFeedbackId());
4446 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4444 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4447 if (expr->is_postfix()) { 4445 if (expr->is_postfix()) {
4448 if (!context()->IsEffect()) { 4446 if (!context()->IsEffect()) {
4449 context()->PlugTOS(); 4447 context()->PlugTOS();
4450 } 4448 }
4451 } else { 4449 } else {
4452 context()->Plug(r0); 4450 context()->Plug(r0);
4453 } 4451 }
4454 break; 4452 break;
4455 } 4453 }
4456 case KEYED_PROPERTY: { 4454 case KEYED_PROPERTY: {
4457 __ Pop(r2, r1); // r1 = key. r2 = receiver. 4455 __ Pop(r2, r1); // r1 = key. r2 = receiver.
4458 Handle<Code> ic = is_classic_mode() 4456 Handle<Code> ic = is_classic_mode()
4459 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4457 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4460 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4458 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4461 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4459 CallIC(ic, expr->CountStoreFeedbackId());
4462 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4460 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4463 if (expr->is_postfix()) { 4461 if (expr->is_postfix()) {
4464 if (!context()->IsEffect()) { 4462 if (!context()->IsEffect()) {
4465 context()->PlugTOS(); 4463 context()->PlugTOS();
4466 } 4464 }
4467 } else { 4465 } else {
4468 context()->Plug(r0); 4466 context()->Plug(r0);
4469 } 4467 }
4470 break; 4468 break;
4471 } 4469 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
4641 __ orr(r2, r0, Operand(r1)); 4639 __ orr(r2, r0, Operand(r1));
4642 patch_site.EmitJumpIfNotSmi(r2, &slow_case); 4640 patch_site.EmitJumpIfNotSmi(r2, &slow_case);
4643 __ cmp(r1, r0); 4641 __ cmp(r1, r0);
4644 Split(cond, if_true, if_false, NULL); 4642 Split(cond, if_true, if_false, NULL);
4645 __ bind(&slow_case); 4643 __ bind(&slow_case);
4646 } 4644 }
4647 4645
4648 // Record position and call the compare IC. 4646 // Record position and call the compare IC.
4649 SetSourcePosition(expr->position()); 4647 SetSourcePosition(expr->position());
4650 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 4648 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
4651 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4649 CallIC(ic, expr->CompareOperationFeedbackId());
4652 patch_site.EmitPatchInfo(); 4650 patch_site.EmitPatchInfo();
4653 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4651 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4654 __ cmp(r0, Operand::Zero()); 4652 __ cmp(r0, Operand::Zero());
4655 Split(cond, if_true, if_false, fall_through); 4653 Split(cond, if_true, if_false, fall_through);
4656 } 4654 }
4657 } 4655 }
4658 4656
4659 // Convert the result of the comparison into one expected for this 4657 // Convert the result of the comparison into one expected for this
4660 // expression's context. 4658 // expression's context.
4661 context()->Plug(if_true, if_false); 4659 context()->Plug(if_true, if_false);
(...skipping 14 matching lines...) Expand all
4676 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4674 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4677 if (expr->op() == Token::EQ_STRICT) { 4675 if (expr->op() == Token::EQ_STRICT) {
4678 Heap::RootListIndex nil_value = nil == kNullValue ? 4676 Heap::RootListIndex nil_value = nil == kNullValue ?
4679 Heap::kNullValueRootIndex : 4677 Heap::kNullValueRootIndex :
4680 Heap::kUndefinedValueRootIndex; 4678 Heap::kUndefinedValueRootIndex;
4681 __ LoadRoot(r1, nil_value); 4679 __ LoadRoot(r1, nil_value);
4682 __ cmp(r0, r1); 4680 __ cmp(r0, r1);
4683 Split(eq, if_true, if_false, fall_through); 4681 Split(eq, if_true, if_false, fall_through);
4684 } else { 4682 } else {
4685 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4683 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
4686 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4684 CallIC(ic, expr->CompareOperationFeedbackId());
4687 __ cmp(r0, Operand(0)); 4685 __ cmp(r0, Operand(0));
4688 Split(ne, if_true, if_false, fall_through); 4686 Split(ne, if_true, if_false, fall_through);
4689 } 4687 }
4690 context()->Plug(if_true, if_false); 4688 context()->Plug(if_true, if_false);
4691 } 4689 }
4692 4690
4693 4691
4694 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4692 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4695 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4693 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4696 context()->Plug(r0); 4694 context()->Plug(r0);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
4919 ASSERT(Memory::uint32_at(interrupt_address_pointer) == 4917 ASSERT(Memory::uint32_at(interrupt_address_pointer) ==
4920 reinterpret_cast<uint32_t>( 4918 reinterpret_cast<uint32_t>(
4921 isolate->builtins()->OsrAfterStackCheck()->entry())); 4919 isolate->builtins()->OsrAfterStackCheck()->entry()));
4922 return OSR_AFTER_STACK_CHECK; 4920 return OSR_AFTER_STACK_CHECK;
4923 } 4921 }
4924 4922
4925 4923
4926 } } // namespace v8::internal 4924 } } // namespace v8::internal
4927 4925
4928 #endif // V8_TARGET_ARCH_ARM 4926 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/debug-arm.cc ('k') | src/ast.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698