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

Side by Side Diff: src/x64/full-codegen-x64.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/x64/debug-x64.cc ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // o rsi: our context 111 // o rsi: our context
112 // o rbp: our caller's frame pointer 112 // o rbp: our caller's frame pointer
113 // o rsp: stack pointer (pointing to return address) 113 // o rsp: stack pointer (pointing to return address)
114 // 114 //
115 // The function builds a JS frame. Please see JavaScriptFrameConstants in 115 // The function builds a JS frame. Please see JavaScriptFrameConstants in
116 // frames-x64.h for its layout. 116 // frames-x64.h for its layout.
117 void FullCodeGenerator::Generate() { 117 void FullCodeGenerator::Generate() {
118 CompilationInfo* info = info_; 118 CompilationInfo* info = info_;
119 handler_table_ = 119 handler_table_ =
120 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 120 isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
121
122 InitializeFeedbackVector();
123
121 profiling_counter_ = isolate()->factory()->NewCell( 124 profiling_counter_ = isolate()->factory()->NewCell(
122 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 125 Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
123 SetFunctionPosition(function()); 126 SetFunctionPosition(function());
124 Comment cmnt(masm_, "[ function compiled by full code generator"); 127 Comment cmnt(masm_, "[ function compiled by full code generator");
125 128
126 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 129 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
127 130
128 #ifdef DEBUG 131 #ifdef DEBUG
129 if (strlen(FLAG_stop_at) > 0 && 132 if (strlen(FLAG_stop_at) > 0 &&
130 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 133 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 if (false_label_ != fall_through_) __ jmp(false_label_); 634 if (false_label_ != fall_through_) __ jmp(false_label_);
632 } 635 }
633 } 636 }
634 637
635 638
636 void FullCodeGenerator::DoTest(Expression* condition, 639 void FullCodeGenerator::DoTest(Expression* condition,
637 Label* if_true, 640 Label* if_true,
638 Label* if_false, 641 Label* if_false,
639 Label* fall_through) { 642 Label* fall_through) {
640 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 643 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
641 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); 644 CallIC(ic, condition->test_id());
642 __ testq(result_register(), result_register()); 645 __ testq(result_register(), result_register());
643 // The stub returns nonzero for true. 646 // The stub returns nonzero for true.
644 Split(not_zero, if_true, if_false, fall_through); 647 Split(not_zero, if_true, if_false, fall_through);
645 } 648 }
646 649
647 650
648 void FullCodeGenerator::Split(Condition cc, 651 void FullCodeGenerator::Split(Condition cc,
649 Label* if_true, 652 Label* if_true,
650 Label* if_false, 653 Label* if_false,
651 Label* fall_through) { 654 Label* fall_through) {
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 __ cmpq(rdx, rax); 987 __ cmpq(rdx, rax);
985 __ j(not_equal, &next_test); 988 __ j(not_equal, &next_test);
986 __ Drop(1); // Switch value is no longer needed. 989 __ Drop(1); // Switch value is no longer needed.
987 __ jmp(clause->body_target()); 990 __ jmp(clause->body_target());
988 __ bind(&slow_case); 991 __ bind(&slow_case);
989 } 992 }
990 993
991 // Record position before stub call for type feedback. 994 // Record position before stub call for type feedback.
992 SetSourcePosition(clause->position()); 995 SetSourcePosition(clause->position());
993 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 996 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
994 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); 997 CallIC(ic, clause->CompareId());
995 patch_site.EmitPatchInfo(); 998 patch_site.EmitPatchInfo();
996 999
997 Label skip; 1000 Label skip;
998 __ jmp(&skip, Label::kNear); 1001 __ jmp(&skip, Label::kNear);
999 PrepareForBailout(clause, TOS_REG); 1002 PrepareForBailout(clause, TOS_REG);
1000 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 1003 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
1001 __ j(not_equal, &next_test); 1004 __ j(not_equal, &next_test);
1002 __ Drop(1); 1005 __ Drop(1);
1003 __ jmp(clause->body_target()); 1006 __ jmp(clause->body_target());
1004 __ bind(&skip); 1007 __ bind(&skip);
(...skipping 23 matching lines...) Expand all
1028 VisitStatements(clause->statements()); 1031 VisitStatements(clause->statements());
1029 } 1032 }
1030 1033
1031 __ bind(nested_statement.break_label()); 1034 __ bind(nested_statement.break_label());
1032 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1035 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1033 } 1036 }
1034 1037
1035 1038
1036 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1039 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1037 Comment cmnt(masm_, "[ ForInStatement"); 1040 Comment cmnt(masm_, "[ ForInStatement");
1041 int slot = stmt->ForInFeedbackSlot();
1038 SetStatementPosition(stmt); 1042 SetStatementPosition(stmt);
1039 1043
1040 Label loop, exit; 1044 Label loop, exit;
1041 ForIn loop_statement(this, stmt); 1045 ForIn loop_statement(this, stmt);
1042 increment_loop_depth(); 1046 increment_loop_depth();
1043 1047
1044 // Get the object to enumerate over. If the object is null or undefined, skip 1048 // Get the object to enumerate over. If the object is null or undefined, skip
1045 // over the loop. See ECMA-262 version 5, section 12.6.4. 1049 // over the loop. See ECMA-262 version 5, section 12.6.4.
1046 VisitForAccumulatorValue(stmt->enumerable()); 1050 VisitForAccumulatorValue(stmt->enumerable());
1047 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 1051 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 __ jmp(&loop); 1120 __ jmp(&loop);
1117 1121
1118 __ bind(&no_descriptors); 1122 __ bind(&no_descriptors);
1119 __ addq(rsp, Immediate(kPointerSize)); 1123 __ addq(rsp, Immediate(kPointerSize));
1120 __ jmp(&exit); 1124 __ jmp(&exit);
1121 1125
1122 // We got a fixed array in register rax. Iterate through that. 1126 // We got a fixed array in register rax. Iterate through that.
1123 Label non_proxy; 1127 Label non_proxy;
1124 __ bind(&fixed_array); 1128 __ bind(&fixed_array);
1125 1129
1126 Handle<Cell> cell = isolate()->factory()->NewCell( 1130 Handle<Object> feedback = Handle<Object>(
1127 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), 1131 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
1128 isolate())); 1132 isolate());
1129 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); 1133 StoreFeedbackVectorSlot(slot, feedback);
1130 __ Move(rbx, cell);
1131 __ Move(FieldOperand(rbx, Cell::kValueOffset),
1132 Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker));
1133 1134
1135 // No need for a write barrier, we are storing a Smi in the feedback vector.
1136 __ Move(rbx, FeedbackVector());
1137 __ Move(FieldOperand(rbx, FixedArray::OffsetOfElementAt(slot)),
1138 Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker));
1134 __ Move(rbx, Smi::FromInt(1)); // Smi indicates slow check 1139 __ Move(rbx, Smi::FromInt(1)); // Smi indicates slow check
1135 __ movp(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object 1140 __ movp(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object
1136 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1141 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1137 __ CmpObjectType(rcx, LAST_JS_PROXY_TYPE, rcx); 1142 __ CmpObjectType(rcx, LAST_JS_PROXY_TYPE, rcx);
1138 __ j(above, &non_proxy); 1143 __ j(above, &non_proxy);
1139 __ Move(rbx, Smi::FromInt(0)); // Zero indicates proxy 1144 __ Move(rbx, Smi::FromInt(0)); // Zero indicates proxy
1140 __ bind(&non_proxy); 1145 __ bind(&non_proxy);
1141 __ push(rbx); // Smi 1146 __ push(rbx); // Smi
1142 __ push(rax); // Array 1147 __ push(rax); // Array
1143 __ movp(rax, FieldOperand(rax, FixedArray::kLengthOffset)); 1148 __ movp(rax, FieldOperand(rax, FixedArray::kLengthOffset));
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 UNREACHABLE(); 1656 UNREACHABLE();
1652 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1657 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1653 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1658 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1654 // Fall through. 1659 // Fall through.
1655 case ObjectLiteral::Property::COMPUTED: 1660 case ObjectLiteral::Property::COMPUTED:
1656 if (key->value()->IsInternalizedString()) { 1661 if (key->value()->IsInternalizedString()) {
1657 if (property->emit_store()) { 1662 if (property->emit_store()) {
1658 VisitForAccumulatorValue(value); 1663 VisitForAccumulatorValue(value);
1659 __ Move(rcx, key->value()); 1664 __ Move(rcx, key->value());
1660 __ movp(rdx, Operand(rsp, 0)); 1665 __ movp(rdx, Operand(rsp, 0));
1661 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); 1666 CallStoreIC(key->LiteralFeedbackId());
1662 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1667 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1663 } else { 1668 } else {
1664 VisitForEffect(value); 1669 VisitForEffect(value);
1665 } 1670 }
1666 break; 1671 break;
1667 } 1672 }
1668 __ push(Operand(rsp, 0)); // Duplicate receiver. 1673 __ push(Operand(rsp, 0)); // Duplicate receiver.
1669 VisitForStackValue(key); 1674 VisitForStackValue(key);
1670 VisitForStackValue(value); 1675 VisitForStackValue(value);
1671 if (property->emit_store()) { 1676 if (property->emit_store()) {
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 __ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next" 2071 __ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next"
2067 __ push(rcx); 2072 __ push(rcx);
2068 __ push(Operand(rsp, 2 * kPointerSize)); // iter 2073 __ push(Operand(rsp, 2 * kPointerSize)); // iter
2069 __ push(rax); // received 2074 __ push(rax); // received
2070 2075
2071 // result = receiver[f](arg); 2076 // result = receiver[f](arg);
2072 __ bind(&l_call); 2077 __ bind(&l_call);
2073 __ movp(rdx, Operand(rsp, kPointerSize)); 2078 __ movp(rdx, Operand(rsp, kPointerSize));
2074 __ movp(rax, Operand(rsp, 2 * kPointerSize)); 2079 __ movp(rax, Operand(rsp, 2 * kPointerSize));
2075 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2080 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2076 CallIC(ic, NOT_CONTEXTUAL, TypeFeedbackId::None()); 2081 CallIC(ic, TypeFeedbackId::None());
2077 __ movp(rdi, rax); 2082 __ movp(rdi, rax);
2078 __ movp(Operand(rsp, 2 * kPointerSize), rdi); 2083 __ movp(Operand(rsp, 2 * kPointerSize), rdi);
2079 CallFunctionStub stub(1, CALL_AS_METHOD); 2084 CallFunctionStub stub(1, CALL_AS_METHOD);
2080 __ CallStub(&stub); 2085 __ CallStub(&stub);
2081 2086
2082 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2087 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2083 __ Drop(1); // The function is still on the stack; drop it. 2088 __ Drop(1); // The function is still on the stack; drop it.
2084 2089
2085 // if (!result.done) goto l_try; 2090 // if (!result.done) goto l_try;
2086 __ bind(&l_loop); 2091 __ bind(&l_loop);
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
2257 SetSourcePosition(prop->position()); 2262 SetSourcePosition(prop->position());
2258 Literal* key = prop->key()->AsLiteral(); 2263 Literal* key = prop->key()->AsLiteral();
2259 __ Move(rcx, key->value()); 2264 __ Move(rcx, key->value());
2260 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2265 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2261 } 2266 }
2262 2267
2263 2268
2264 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2269 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2265 SetSourcePosition(prop->position()); 2270 SetSourcePosition(prop->position());
2266 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2271 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2267 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2272 CallIC(ic, prop->PropertyFeedbackId());
2268 } 2273 }
2269 2274
2270 2275
2271 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2276 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2272 Token::Value op, 2277 Token::Value op,
2273 OverwriteMode mode, 2278 OverwriteMode mode,
2274 Expression* left, 2279 Expression* left,
2275 Expression* right) { 2280 Expression* right) {
2276 // Do combined smi check of the operands. Left operand is on the 2281 // Do combined smi check of the operands. Left operand is on the
2277 // stack (popped into rdx). Right operand is in rax but moved into 2282 // stack (popped into rdx). Right operand is in rax but moved into
2278 // rcx to make the shifts easier. 2283 // rcx to make the shifts easier.
2279 Label done, stub_call, smi_case; 2284 Label done, stub_call, smi_case;
2280 __ pop(rdx); 2285 __ pop(rdx);
2281 __ movp(rcx, rax); 2286 __ movp(rcx, rax);
2282 __ or_(rax, rdx); 2287 __ or_(rax, rdx);
2283 JumpPatchSite patch_site(masm_); 2288 JumpPatchSite patch_site(masm_);
2284 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); 2289 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear);
2285 2290
2286 __ bind(&stub_call); 2291 __ bind(&stub_call);
2287 __ movp(rax, rcx); 2292 __ movp(rax, rcx);
2288 BinaryOpICStub stub(op, mode); 2293 BinaryOpICStub stub(op, mode);
2289 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2294 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2290 expr->BinaryOperationFeedbackId());
2291 patch_site.EmitPatchInfo(); 2295 patch_site.EmitPatchInfo();
2292 __ jmp(&done, Label::kNear); 2296 __ jmp(&done, Label::kNear);
2293 2297
2294 __ bind(&smi_case); 2298 __ bind(&smi_case);
2295 switch (op) { 2299 switch (op) {
2296 case Token::SAR: 2300 case Token::SAR:
2297 __ SmiShiftArithmeticRight(rax, rdx, rcx); 2301 __ SmiShiftArithmeticRight(rax, rdx, rcx);
2298 break; 2302 break;
2299 case Token::SHL: 2303 case Token::SHL:
2300 __ SmiShiftLeft(rax, rdx, rcx); 2304 __ SmiShiftLeft(rax, rdx, rcx);
(...skipping 28 matching lines...) Expand all
2329 context()->Plug(rax); 2333 context()->Plug(rax);
2330 } 2334 }
2331 2335
2332 2336
2333 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 2337 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
2334 Token::Value op, 2338 Token::Value op,
2335 OverwriteMode mode) { 2339 OverwriteMode mode) {
2336 __ pop(rdx); 2340 __ pop(rdx);
2337 BinaryOpICStub stub(op, mode); 2341 BinaryOpICStub stub(op, mode);
2338 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2342 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2339 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2343 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2340 expr->BinaryOperationFeedbackId());
2341 patch_site.EmitPatchInfo(); 2344 patch_site.EmitPatchInfo();
2342 context()->Plug(rax); 2345 context()->Plug(rax);
2343 } 2346 }
2344 2347
2345 2348
2346 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2349 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2347 // Invalid left-hand sides are rewritten by the parser to have a 'throw 2350 // Invalid left-hand sides are rewritten by the parser to have a 'throw
2348 // ReferenceError' on the left-hand side. 2351 // ReferenceError' on the left-hand side.
2349 if (!expr->IsValidLeftHandSide()) { 2352 if (!expr->IsValidLeftHandSide()) {
2350 VisitForEffect(expr); 2353 VisitForEffect(expr);
(...skipping 17 matching lines...) Expand all
2368 EffectContext context(this); 2371 EffectContext context(this);
2369 EmitVariableAssignment(var, Token::ASSIGN); 2372 EmitVariableAssignment(var, Token::ASSIGN);
2370 break; 2373 break;
2371 } 2374 }
2372 case NAMED_PROPERTY: { 2375 case NAMED_PROPERTY: {
2373 __ push(rax); // Preserve value. 2376 __ push(rax); // Preserve value.
2374 VisitForAccumulatorValue(prop->obj()); 2377 VisitForAccumulatorValue(prop->obj());
2375 __ movp(rdx, rax); 2378 __ movp(rdx, rax);
2376 __ pop(rax); // Restore value. 2379 __ pop(rax); // Restore value.
2377 __ Move(rcx, prop->key()->AsLiteral()->value()); 2380 __ Move(rcx, prop->key()->AsLiteral()->value());
2378 CallStoreIC(NOT_CONTEXTUAL); 2381 CallStoreIC();
2379 break; 2382 break;
2380 } 2383 }
2381 case KEYED_PROPERTY: { 2384 case KEYED_PROPERTY: {
2382 __ push(rax); // Preserve value. 2385 __ push(rax); // Preserve value.
2383 VisitForStackValue(prop->obj()); 2386 VisitForStackValue(prop->obj());
2384 VisitForAccumulatorValue(prop->key()); 2387 VisitForAccumulatorValue(prop->key());
2385 __ movp(rcx, rax); 2388 __ movp(rcx, rax);
2386 __ pop(rdx); 2389 __ pop(rdx);
2387 __ pop(rax); // Restore value. 2390 __ pop(rax); // Restore value.
2388 Handle<Code> ic = is_classic_mode() 2391 Handle<Code> ic = is_classic_mode()
2389 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2392 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2390 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2393 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2391 CallIC(ic); 2394 CallIC(ic);
2392 break; 2395 break;
2393 } 2396 }
2394 } 2397 }
2395 context()->Plug(rax); 2398 context()->Plug(rax);
2396 } 2399 }
2397 2400
2398 2401
2399 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2402 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2400 Token::Value op) { 2403 Token::Value op) {
2401 if (var->IsUnallocated()) { 2404 if (var->IsUnallocated()) {
2402 // Global var, const, or let. 2405 // Global var, const, or let.
2403 __ Move(rcx, var->name()); 2406 __ Move(rcx, var->name());
2404 __ movp(rdx, GlobalObjectOperand()); 2407 __ movp(rdx, GlobalObjectOperand());
2405 CallStoreIC(CONTEXTUAL); 2408 CallStoreIC();
2406 } else if (op == Token::INIT_CONST) { 2409 } else if (op == Token::INIT_CONST) {
2407 // Const initializers need a write barrier. 2410 // Const initializers need a write barrier.
2408 ASSERT(!var->IsParameter()); // No const parameters. 2411 ASSERT(!var->IsParameter()); // No const parameters.
2409 if (var->IsStackLocal()) { 2412 if (var->IsStackLocal()) {
2410 Label skip; 2413 Label skip;
2411 __ movp(rdx, StackOperand(var)); 2414 __ movp(rdx, StackOperand(var));
2412 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); 2415 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
2413 __ j(not_equal, &skip); 2416 __ j(not_equal, &skip);
2414 __ movp(StackOperand(var), rax); 2417 __ movp(StackOperand(var), rax);
2415 __ bind(&skip); 2418 __ bind(&skip);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2486 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2489 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2487 // Assignment to a property, using a named store IC. 2490 // Assignment to a property, using a named store IC.
2488 Property* prop = expr->target()->AsProperty(); 2491 Property* prop = expr->target()->AsProperty();
2489 ASSERT(prop != NULL); 2492 ASSERT(prop != NULL);
2490 ASSERT(prop->key()->AsLiteral() != NULL); 2493 ASSERT(prop->key()->AsLiteral() != NULL);
2491 2494
2492 // Record source code position before IC call. 2495 // Record source code position before IC call.
2493 SetSourcePosition(expr->position()); 2496 SetSourcePosition(expr->position());
2494 __ Move(rcx, prop->key()->AsLiteral()->value()); 2497 __ Move(rcx, prop->key()->AsLiteral()->value());
2495 __ pop(rdx); 2498 __ pop(rdx);
2496 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2499 CallStoreIC(expr->AssignmentFeedbackId());
2497 2500
2498 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2501 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2499 context()->Plug(rax); 2502 context()->Plug(rax);
2500 } 2503 }
2501 2504
2502 2505
2503 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2506 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2504 // Assignment to a property, using a keyed store IC. 2507 // Assignment to a property, using a keyed store IC.
2505 2508
2506 __ pop(rcx); 2509 __ pop(rcx);
2507 __ pop(rdx); 2510 __ pop(rdx);
2508 // Record source code position before IC call. 2511 // Record source code position before IC call.
2509 SetSourcePosition(expr->position()); 2512 SetSourcePosition(expr->position());
2510 Handle<Code> ic = is_classic_mode() 2513 Handle<Code> ic = is_classic_mode()
2511 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2514 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2512 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2515 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2513 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2516 CallIC(ic, expr->AssignmentFeedbackId());
2514 2517
2515 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2518 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2516 context()->Plug(rax); 2519 context()->Plug(rax);
2517 } 2520 }
2518 2521
2519 2522
2520 void FullCodeGenerator::VisitProperty(Property* expr) { 2523 void FullCodeGenerator::VisitProperty(Property* expr) {
2521 Comment cmnt(masm_, "[ Property"); 2524 Comment cmnt(masm_, "[ Property");
2522 Expression* key = expr->key(); 2525 Expression* key = expr->key();
2523 2526
2524 if (key->IsPropertyName()) { 2527 if (key->IsPropertyName()) {
2525 VisitForAccumulatorValue(expr->obj()); 2528 VisitForAccumulatorValue(expr->obj());
2526 EmitNamedPropertyLoad(expr); 2529 EmitNamedPropertyLoad(expr);
2527 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2530 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2528 context()->Plug(rax); 2531 context()->Plug(rax);
2529 } else { 2532 } else {
2530 VisitForStackValue(expr->obj()); 2533 VisitForStackValue(expr->obj());
2531 VisitForAccumulatorValue(expr->key()); 2534 VisitForAccumulatorValue(expr->key());
2532 __ pop(rdx); 2535 __ pop(rdx);
2533 EmitKeyedPropertyLoad(expr); 2536 EmitKeyedPropertyLoad(expr);
2534 context()->Plug(rax); 2537 context()->Plug(rax);
2535 } 2538 }
2536 } 2539 }
2537 2540
2538 2541
2539 void FullCodeGenerator::CallIC(Handle<Code> code, 2542 void FullCodeGenerator::CallIC(Handle<Code> code,
2540 ContextualMode mode,
2541 TypeFeedbackId ast_id) { 2543 TypeFeedbackId ast_id) {
2542 ic_total_count_++; 2544 ic_total_count_++;
2543 ASSERT(mode != CONTEXTUAL || ast_id.IsNone());
2544 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2545 __ call(code, RelocInfo::CODE_TARGET, ast_id);
2545 } 2546 }
2546 2547
2547 2548
2548 // Code common for calls using the IC. 2549 // Code common for calls using the IC.
2549 void FullCodeGenerator::EmitCallWithIC(Call* expr) { 2550 void FullCodeGenerator::EmitCallWithIC(Call* expr) {
2550 Expression* callee = expr->expression(); 2551 Expression* callee = expr->expression();
2551 ZoneList<Expression*>* args = expr->arguments(); 2552 ZoneList<Expression*>* args = expr->arguments();
2552 int arg_count = args->length(); 2553 int arg_count = args->length();
2553 2554
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2643 int arg_count = args->length(); 2644 int arg_count = args->length();
2644 { PreservePositionScope scope(masm()->positions_recorder()); 2645 { PreservePositionScope scope(masm()->positions_recorder());
2645 for (int i = 0; i < arg_count; i++) { 2646 for (int i = 0; i < arg_count; i++) {
2646 VisitForStackValue(args->at(i)); 2647 VisitForStackValue(args->at(i));
2647 } 2648 }
2648 } 2649 }
2649 // Record source position for debugger. 2650 // Record source position for debugger.
2650 SetSourcePosition(expr->position()); 2651 SetSourcePosition(expr->position());
2651 2652
2652 Handle<Object> uninitialized = 2653 Handle<Object> uninitialized =
2653 TypeFeedbackCells::UninitializedSentinel(isolate()); 2654 TypeFeedbackInfo::UninitializedSentinel(isolate());
2654 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2655 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
2655 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); 2656 __ Move(rbx, FeedbackVector());
2656 __ Move(rbx, cell); 2657 __ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot()));
2657 2658
2658 // Record call targets in unoptimized code. 2659 // Record call targets in unoptimized code.
2659 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); 2660 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2660 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); 2661 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
2661 __ CallStub(&stub, expr->CallFeedbackId()); 2662 __ CallStub(&stub);
2662 RecordJSReturnSite(expr); 2663 RecordJSReturnSite(expr);
2663 // Restore context register. 2664 // Restore context register.
2664 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2665 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2665 // Discard the function left on TOS. 2666 // Discard the function left on TOS.
2666 context()->DropAndPlug(1, rax); 2667 context()->DropAndPlug(1, rax);
2667 } 2668 }
2668 2669
2669 2670
2670 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2671 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2671 // Push copy of the first argument or undefined if it doesn't exist. 2672 // Push copy of the first argument or undefined if it doesn't exist.
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2823 // Call the construct call builtin that handles allocation and 2824 // Call the construct call builtin that handles allocation and
2824 // constructor invocation. 2825 // constructor invocation.
2825 SetSourcePosition(expr->position()); 2826 SetSourcePosition(expr->position());
2826 2827
2827 // Load function and argument count into rdi and rax. 2828 // Load function and argument count into rdi and rax.
2828 __ Set(rax, arg_count); 2829 __ Set(rax, arg_count);
2829 __ movp(rdi, Operand(rsp, arg_count * kPointerSize)); 2830 __ movp(rdi, Operand(rsp, arg_count * kPointerSize));
2830 2831
2831 // Record call targets in unoptimized code, but not in the snapshot. 2832 // Record call targets in unoptimized code, but not in the snapshot.
2832 Handle<Object> uninitialized = 2833 Handle<Object> uninitialized =
2833 TypeFeedbackCells::UninitializedSentinel(isolate()); 2834 TypeFeedbackInfo::UninitializedSentinel(isolate());
2834 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2835 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
2835 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); 2836 __ Move(rbx, FeedbackVector());
2836 __ Move(rbx, cell); 2837 __ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot()));
2837 2838
2838 CallConstructStub stub(RECORD_CALL_TARGET); 2839 CallConstructStub stub(RECORD_CALL_TARGET);
2839 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2840 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2840 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2841 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2841 context()->Plug(rax); 2842 context()->Plug(rax);
2842 } 2843 }
2843 2844
2844 2845
2845 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2846 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2846 ZoneList<Expression*>* args = expr->arguments(); 2847 ZoneList<Expression*>* args = expr->arguments();
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after
4402 } 4403 }
4403 4404
4404 // Record position before stub call. 4405 // Record position before stub call.
4405 SetSourcePosition(expr->position()); 4406 SetSourcePosition(expr->position());
4406 4407
4407 // Call stub for +1/-1. 4408 // Call stub for +1/-1.
4408 __ bind(&stub_call); 4409 __ bind(&stub_call);
4409 __ movp(rdx, rax); 4410 __ movp(rdx, rax);
4410 __ Move(rax, Smi::FromInt(1)); 4411 __ Move(rax, Smi::FromInt(1));
4411 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); 4412 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE);
4412 CallIC(stub.GetCode(isolate()), 4413 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
4413 NOT_CONTEXTUAL,
4414 expr->CountBinOpFeedbackId());
4415 patch_site.EmitPatchInfo(); 4414 patch_site.EmitPatchInfo();
4416 __ bind(&done); 4415 __ bind(&done);
4417 4416
4418 // Store the value returned in rax. 4417 // Store the value returned in rax.
4419 switch (assign_type) { 4418 switch (assign_type) {
4420 case VARIABLE: 4419 case VARIABLE:
4421 if (expr->is_postfix()) { 4420 if (expr->is_postfix()) {
4422 // Perform the assignment as if via '='. 4421 // Perform the assignment as if via '='.
4423 { EffectContext context(this); 4422 { EffectContext context(this);
4424 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4423 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
(...skipping 10 matching lines...) Expand all
4435 // Perform the assignment as if via '='. 4434 // Perform the assignment as if via '='.
4436 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4435 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4437 Token::ASSIGN); 4436 Token::ASSIGN);
4438 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4437 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4439 context()->Plug(rax); 4438 context()->Plug(rax);
4440 } 4439 }
4441 break; 4440 break;
4442 case NAMED_PROPERTY: { 4441 case NAMED_PROPERTY: {
4443 __ Move(rcx, prop->key()->AsLiteral()->value()); 4442 __ Move(rcx, prop->key()->AsLiteral()->value());
4444 __ pop(rdx); 4443 __ pop(rdx);
4445 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4444 CallStoreIC(expr->CountStoreFeedbackId());
4446 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4445 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4447 if (expr->is_postfix()) { 4446 if (expr->is_postfix()) {
4448 if (!context()->IsEffect()) { 4447 if (!context()->IsEffect()) {
4449 context()->PlugTOS(); 4448 context()->PlugTOS();
4450 } 4449 }
4451 } else { 4450 } else {
4452 context()->Plug(rax); 4451 context()->Plug(rax);
4453 } 4452 }
4454 break; 4453 break;
4455 } 4454 }
4456 case KEYED_PROPERTY: { 4455 case KEYED_PROPERTY: {
4457 __ pop(rcx); 4456 __ pop(rcx);
4458 __ pop(rdx); 4457 __ pop(rdx);
4459 Handle<Code> ic = is_classic_mode() 4458 Handle<Code> ic = is_classic_mode()
4460 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4459 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4461 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4460 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4462 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4461 CallIC(ic, expr->CountStoreFeedbackId());
4463 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4462 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4464 if (expr->is_postfix()) { 4463 if (expr->is_postfix()) {
4465 if (!context()->IsEffect()) { 4464 if (!context()->IsEffect()) {
4466 context()->PlugTOS(); 4465 context()->PlugTOS();
4467 } 4466 }
4468 } else { 4467 } else {
4469 context()->Plug(rax); 4468 context()->Plug(rax);
4470 } 4469 }
4471 break; 4470 break;
4472 } 4471 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
4640 __ or_(rcx, rax); 4639 __ or_(rcx, rax);
4641 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); 4640 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear);
4642 __ cmpq(rdx, rax); 4641 __ cmpq(rdx, rax);
4643 Split(cc, if_true, if_false, NULL); 4642 Split(cc, if_true, if_false, NULL);
4644 __ bind(&slow_case); 4643 __ bind(&slow_case);
4645 } 4644 }
4646 4645
4647 // Record position and call the compare IC. 4646 // Record position and call the compare IC.
4648 SetSourcePosition(expr->position()); 4647 SetSourcePosition(expr->position());
4649 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 4648 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
4650 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4649 CallIC(ic, expr->CompareOperationFeedbackId());
4651 patch_site.EmitPatchInfo(); 4650 patch_site.EmitPatchInfo();
4652 4651
4653 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4652 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4654 __ testq(rax, rax); 4653 __ testq(rax, rax);
4655 Split(cc, if_true, if_false, fall_through); 4654 Split(cc, if_true, if_false, fall_through);
4656 } 4655 }
4657 } 4656 }
4658 4657
4659 // Convert the result of the comparison into one expected for this 4658 // Convert the result of the comparison into one expected for this
4660 // expression's context. 4659 // expression's context.
(...skipping 14 matching lines...) Expand all
4675 VisitForAccumulatorValue(sub_expr); 4674 VisitForAccumulatorValue(sub_expr);
4676 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4675 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4677 if (expr->op() == Token::EQ_STRICT) { 4676 if (expr->op() == Token::EQ_STRICT) {
4678 Heap::RootListIndex nil_value = nil == kNullValue ? 4677 Heap::RootListIndex nil_value = nil == kNullValue ?
4679 Heap::kNullValueRootIndex : 4678 Heap::kNullValueRootIndex :
4680 Heap::kUndefinedValueRootIndex; 4679 Heap::kUndefinedValueRootIndex;
4681 __ CompareRoot(rax, nil_value); 4680 __ CompareRoot(rax, nil_value);
4682 Split(equal, if_true, if_false, fall_through); 4681 Split(equal, if_true, if_false, fall_through);
4683 } else { 4682 } else {
4684 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4683 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
4685 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4684 CallIC(ic, expr->CompareOperationFeedbackId());
4686 __ testq(rax, rax); 4685 __ testq(rax, rax);
4687 Split(not_zero, if_true, if_false, fall_through); 4686 Split(not_zero, if_true, if_false, fall_through);
4688 } 4687 }
4689 context()->Plug(if_true, if_false); 4688 context()->Plug(if_true, if_false);
4690 } 4689 }
4691 4690
4692 4691
4693 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4692 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4694 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 4693 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
4695 context()->Plug(rax); 4694 context()->Plug(rax);
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
4907 4906
4908 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4907 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4909 Assembler::target_address_at(call_target_address)); 4908 Assembler::target_address_at(call_target_address));
4910 return OSR_AFTER_STACK_CHECK; 4909 return OSR_AFTER_STACK_CHECK;
4911 } 4910 }
4912 4911
4913 4912
4914 } } // namespace v8::internal 4913 } } // namespace v8::internal
4915 4914
4916 #endif // V8_TARGET_ARCH_X64 4915 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/debug-x64.cc ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698