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

Side by Side Diff: src/ia32/full-codegen-ia32.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/ia32/debug-ia32.cc ('k') | src/ic.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 esi: our context 111 // o esi: our context
112 // o ebp: our caller's frame pointer 112 // o ebp: our caller's frame pointer
113 // o esp: stack pointer (pointing to return address) 113 // o esp: 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-ia32.h for its layout. 116 // frames-ia32.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 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 if (false_label_ != fall_through_) __ jmp(false_label_); 622 if (false_label_ != fall_through_) __ jmp(false_label_);
620 } 623 }
621 } 624 }
622 625
623 626
624 void FullCodeGenerator::DoTest(Expression* condition, 627 void FullCodeGenerator::DoTest(Expression* condition,
625 Label* if_true, 628 Label* if_true,
626 Label* if_false, 629 Label* if_false,
627 Label* fall_through) { 630 Label* fall_through) {
628 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 631 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
629 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); 632 CallIC(ic, condition->test_id());
630 __ test(result_register(), result_register()); 633 __ test(result_register(), result_register());
631 // The stub returns nonzero for true. 634 // The stub returns nonzero for true.
632 Split(not_zero, if_true, if_false, fall_through); 635 Split(not_zero, if_true, if_false, fall_through);
633 } 636 }
634 637
635 638
636 void FullCodeGenerator::Split(Condition cc, 639 void FullCodeGenerator::Split(Condition cc,
637 Label* if_true, 640 Label* if_true,
638 Label* if_false, 641 Label* if_false,
639 Label* fall_through) { 642 Label* fall_through) {
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 __ cmp(edx, eax); 973 __ cmp(edx, eax);
971 __ j(not_equal, &next_test); 974 __ j(not_equal, &next_test);
972 __ Drop(1); // Switch value is no longer needed. 975 __ Drop(1); // Switch value is no longer needed.
973 __ jmp(clause->body_target()); 976 __ jmp(clause->body_target());
974 __ bind(&slow_case); 977 __ bind(&slow_case);
975 } 978 }
976 979
977 // Record position before stub call for type feedback. 980 // Record position before stub call for type feedback.
978 SetSourcePosition(clause->position()); 981 SetSourcePosition(clause->position());
979 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 982 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
980 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); 983 CallIC(ic, clause->CompareId());
981 patch_site.EmitPatchInfo(); 984 patch_site.EmitPatchInfo();
982 985
983 Label skip; 986 Label skip;
984 __ jmp(&skip, Label::kNear); 987 __ jmp(&skip, Label::kNear);
985 PrepareForBailout(clause, TOS_REG); 988 PrepareForBailout(clause, TOS_REG);
986 __ cmp(eax, isolate()->factory()->true_value()); 989 __ cmp(eax, isolate()->factory()->true_value());
987 __ j(not_equal, &next_test); 990 __ j(not_equal, &next_test);
988 __ Drop(1); 991 __ Drop(1);
989 __ jmp(clause->body_target()); 992 __ jmp(clause->body_target());
990 __ bind(&skip); 993 __ bind(&skip);
(...skipping 23 matching lines...) Expand all
1014 VisitStatements(clause->statements()); 1017 VisitStatements(clause->statements());
1015 } 1018 }
1016 1019
1017 __ bind(nested_statement.break_label()); 1020 __ bind(nested_statement.break_label());
1018 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1021 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1019 } 1022 }
1020 1023
1021 1024
1022 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1025 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1023 Comment cmnt(masm_, "[ ForInStatement"); 1026 Comment cmnt(masm_, "[ ForInStatement");
1027 int slot = stmt->ForInFeedbackSlot();
1028
1024 SetStatementPosition(stmt); 1029 SetStatementPosition(stmt);
1025 1030
1026 Label loop, exit; 1031 Label loop, exit;
1027 ForIn loop_statement(this, stmt); 1032 ForIn loop_statement(this, stmt);
1028 increment_loop_depth(); 1033 increment_loop_depth();
1029 1034
1030 // Get the object to enumerate over. If the object is null or undefined, skip 1035 // Get the object to enumerate over. If the object is null or undefined, skip
1031 // over the loop. See ECMA-262 version 5, section 12.6.4. 1036 // over the loop. See ECMA-262 version 5, section 12.6.4.
1032 VisitForAccumulatorValue(stmt->enumerable()); 1037 VisitForAccumulatorValue(stmt->enumerable());
1033 __ cmp(eax, isolate()->factory()->undefined_value()); 1038 __ cmp(eax, isolate()->factory()->undefined_value());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 __ jmp(&loop); 1097 __ jmp(&loop);
1093 1098
1094 __ bind(&no_descriptors); 1099 __ bind(&no_descriptors);
1095 __ add(esp, Immediate(kPointerSize)); 1100 __ add(esp, Immediate(kPointerSize));
1096 __ jmp(&exit); 1101 __ jmp(&exit);
1097 1102
1098 // We got a fixed array in register eax. Iterate through that. 1103 // We got a fixed array in register eax. Iterate through that.
1099 Label non_proxy; 1104 Label non_proxy;
1100 __ bind(&fixed_array); 1105 __ bind(&fixed_array);
1101 1106
1102 Handle<Cell> cell = isolate()->factory()->NewCell( 1107 Handle<Object> feedback = Handle<Object>(
1103 Handle<Object>(Smi::FromInt(TypeFeedbackCells::kForInFastCaseMarker), 1108 Smi::FromInt(TypeFeedbackInfo::kForInFastCaseMarker),
1104 isolate())); 1109 isolate());
1105 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); 1110 StoreFeedbackVectorSlot(slot, feedback);
1106 __ LoadHeapObject(ebx, cell); 1111
1107 __ mov(FieldOperand(ebx, Cell::kValueOffset), 1112 // No need for a write barrier, we are storing a Smi in the feedback vector.
1108 Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); 1113 __ LoadHeapObject(ebx, FeedbackVector());
1114 __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)),
1115 Immediate(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker)));
1109 1116
1110 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check 1117 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check
1111 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object 1118 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object
1112 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1119 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
1113 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); 1120 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx);
1114 __ j(above, &non_proxy); 1121 __ j(above, &non_proxy);
1115 __ Set(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy 1122 __ Set(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy
1116 __ bind(&non_proxy); 1123 __ bind(&non_proxy);
1117 __ push(ebx); // Smi 1124 __ push(ebx); // Smi
1118 __ push(eax); // Array 1125 __ push(eax); // Array
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
1626 UNREACHABLE(); 1633 UNREACHABLE();
1627 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1634 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1628 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1635 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1629 // Fall through. 1636 // Fall through.
1630 case ObjectLiteral::Property::COMPUTED: 1637 case ObjectLiteral::Property::COMPUTED:
1631 if (key->value()->IsInternalizedString()) { 1638 if (key->value()->IsInternalizedString()) {
1632 if (property->emit_store()) { 1639 if (property->emit_store()) {
1633 VisitForAccumulatorValue(value); 1640 VisitForAccumulatorValue(value);
1634 __ mov(ecx, Immediate(key->value())); 1641 __ mov(ecx, Immediate(key->value()));
1635 __ mov(edx, Operand(esp, 0)); 1642 __ mov(edx, Operand(esp, 0));
1636 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); 1643 CallStoreIC(key->LiteralFeedbackId());
1637 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1644 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1638 } else { 1645 } else {
1639 VisitForEffect(value); 1646 VisitForEffect(value);
1640 } 1647 }
1641 break; 1648 break;
1642 } 1649 }
1643 __ push(Operand(esp, 0)); // Duplicate receiver. 1650 __ push(Operand(esp, 0)); // Duplicate receiver.
1644 VisitForStackValue(key); 1651 VisitForStackValue(key);
1645 VisitForStackValue(value); 1652 VisitForStackValue(value);
1646 if (property->emit_store()) { 1653 if (property->emit_store()) {
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 __ bind(&l_next); 2047 __ bind(&l_next);
2041 __ mov(ecx, isolate()->factory()->next_string()); // "next" 2048 __ mov(ecx, isolate()->factory()->next_string()); // "next"
2042 __ push(ecx); 2049 __ push(ecx);
2043 __ push(Operand(esp, 2 * kPointerSize)); // iter 2050 __ push(Operand(esp, 2 * kPointerSize)); // iter
2044 __ push(eax); // received 2051 __ push(eax); // received
2045 2052
2046 // result = receiver[f](arg); 2053 // result = receiver[f](arg);
2047 __ bind(&l_call); 2054 __ bind(&l_call);
2048 __ mov(edx, Operand(esp, kPointerSize)); 2055 __ mov(edx, Operand(esp, kPointerSize));
2049 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2056 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2050 CallIC(ic, NOT_CONTEXTUAL, TypeFeedbackId::None()); 2057 CallIC(ic, TypeFeedbackId::None());
2051 __ mov(edi, eax); 2058 __ mov(edi, eax);
2052 __ mov(Operand(esp, 2 * kPointerSize), edi); 2059 __ mov(Operand(esp, 2 * kPointerSize), edi);
2053 CallFunctionStub stub(1, CALL_AS_METHOD); 2060 CallFunctionStub stub(1, CALL_AS_METHOD);
2054 __ CallStub(&stub); 2061 __ CallStub(&stub);
2055 2062
2056 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2063 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2057 __ Drop(1); // The function is still on the stack; drop it. 2064 __ Drop(1); // The function is still on the stack; drop it.
2058 2065
2059 // if (!result.done) goto l_try; 2066 // if (!result.done) goto l_try;
2060 __ bind(&l_loop); 2067 __ bind(&l_loop);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2230 Literal* key = prop->key()->AsLiteral(); 2237 Literal* key = prop->key()->AsLiteral();
2231 ASSERT(!key->value()->IsSmi()); 2238 ASSERT(!key->value()->IsSmi());
2232 __ mov(ecx, Immediate(key->value())); 2239 __ mov(ecx, Immediate(key->value()));
2233 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2240 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2234 } 2241 }
2235 2242
2236 2243
2237 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2244 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2238 SetSourcePosition(prop->position()); 2245 SetSourcePosition(prop->position());
2239 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2246 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2240 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2247 CallIC(ic, prop->PropertyFeedbackId());
2241 } 2248 }
2242 2249
2243 2250
2244 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2251 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2245 Token::Value op, 2252 Token::Value op,
2246 OverwriteMode mode, 2253 OverwriteMode mode,
2247 Expression* left, 2254 Expression* left,
2248 Expression* right) { 2255 Expression* right) {
2249 // Do combined smi check of the operands. Left operand is on the 2256 // Do combined smi check of the operands. Left operand is on the
2250 // stack. Right operand is in eax. 2257 // stack. Right operand is in eax.
2251 Label smi_case, done, stub_call; 2258 Label smi_case, done, stub_call;
2252 __ pop(edx); 2259 __ pop(edx);
2253 __ mov(ecx, eax); 2260 __ mov(ecx, eax);
2254 __ or_(eax, edx); 2261 __ or_(eax, edx);
2255 JumpPatchSite patch_site(masm_); 2262 JumpPatchSite patch_site(masm_);
2256 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 2263 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
2257 2264
2258 __ bind(&stub_call); 2265 __ bind(&stub_call);
2259 __ mov(eax, ecx); 2266 __ mov(eax, ecx);
2260 BinaryOpICStub stub(op, mode); 2267 BinaryOpICStub stub(op, mode);
2261 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2268 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2262 expr->BinaryOperationFeedbackId());
2263 patch_site.EmitPatchInfo(); 2269 patch_site.EmitPatchInfo();
2264 __ jmp(&done, Label::kNear); 2270 __ jmp(&done, Label::kNear);
2265 2271
2266 // Smi case. 2272 // Smi case.
2267 __ bind(&smi_case); 2273 __ bind(&smi_case);
2268 __ mov(eax, edx); // Copy left operand in case of a stub call. 2274 __ mov(eax, edx); // Copy left operand in case of a stub call.
2269 2275
2270 switch (op) { 2276 switch (op) {
2271 case Token::SAR: 2277 case Token::SAR:
2272 __ SmiUntag(eax); 2278 __ SmiUntag(eax);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2337 context()->Plug(eax); 2343 context()->Plug(eax);
2338 } 2344 }
2339 2345
2340 2346
2341 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 2347 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
2342 Token::Value op, 2348 Token::Value op,
2343 OverwriteMode mode) { 2349 OverwriteMode mode) {
2344 __ pop(edx); 2350 __ pop(edx);
2345 BinaryOpICStub stub(op, mode); 2351 BinaryOpICStub stub(op, mode);
2346 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2352 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2347 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, 2353 CallIC(stub.GetCode(isolate()), expr->BinaryOperationFeedbackId());
2348 expr->BinaryOperationFeedbackId());
2349 patch_site.EmitPatchInfo(); 2354 patch_site.EmitPatchInfo();
2350 context()->Plug(eax); 2355 context()->Plug(eax);
2351 } 2356 }
2352 2357
2353 2358
2354 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2359 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2355 // Invalid left-hand sides are rewritten by the parser to have a 'throw 2360 // Invalid left-hand sides are rewritten by the parser to have a 'throw
2356 // ReferenceError' on the left-hand side. 2361 // ReferenceError' on the left-hand side.
2357 if (!expr->IsValidLeftHandSide()) { 2362 if (!expr->IsValidLeftHandSide()) {
2358 VisitForEffect(expr); 2363 VisitForEffect(expr);
(...skipping 17 matching lines...) Expand all
2376 EffectContext context(this); 2381 EffectContext context(this);
2377 EmitVariableAssignment(var, Token::ASSIGN); 2382 EmitVariableAssignment(var, Token::ASSIGN);
2378 break; 2383 break;
2379 } 2384 }
2380 case NAMED_PROPERTY: { 2385 case NAMED_PROPERTY: {
2381 __ push(eax); // Preserve value. 2386 __ push(eax); // Preserve value.
2382 VisitForAccumulatorValue(prop->obj()); 2387 VisitForAccumulatorValue(prop->obj());
2383 __ mov(edx, eax); 2388 __ mov(edx, eax);
2384 __ pop(eax); // Restore value. 2389 __ pop(eax); // Restore value.
2385 __ mov(ecx, prop->key()->AsLiteral()->value()); 2390 __ mov(ecx, prop->key()->AsLiteral()->value());
2386 CallStoreIC(NOT_CONTEXTUAL); 2391 CallStoreIC();
2387 break; 2392 break;
2388 } 2393 }
2389 case KEYED_PROPERTY: { 2394 case KEYED_PROPERTY: {
2390 __ push(eax); // Preserve value. 2395 __ push(eax); // Preserve value.
2391 VisitForStackValue(prop->obj()); 2396 VisitForStackValue(prop->obj());
2392 VisitForAccumulatorValue(prop->key()); 2397 VisitForAccumulatorValue(prop->key());
2393 __ mov(ecx, eax); 2398 __ mov(ecx, eax);
2394 __ pop(edx); // Receiver. 2399 __ pop(edx); // Receiver.
2395 __ pop(eax); // Restore value. 2400 __ pop(eax); // Restore value.
2396 Handle<Code> ic = is_classic_mode() 2401 Handle<Code> ic = is_classic_mode()
2397 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2402 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2398 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2403 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2399 CallIC(ic); 2404 CallIC(ic);
2400 break; 2405 break;
2401 } 2406 }
2402 } 2407 }
2403 context()->Plug(eax); 2408 context()->Plug(eax);
2404 } 2409 }
2405 2410
2406 2411
2407 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2412 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2408 Token::Value op) { 2413 Token::Value op) {
2409 if (var->IsUnallocated()) { 2414 if (var->IsUnallocated()) {
2410 // Global var, const, or let. 2415 // Global var, const, or let.
2411 __ mov(ecx, var->name()); 2416 __ mov(ecx, var->name());
2412 __ mov(edx, GlobalObjectOperand()); 2417 __ mov(edx, GlobalObjectOperand());
2413 CallStoreIC(CONTEXTUAL); 2418 CallStoreIC();
2414 } else if (op == Token::INIT_CONST) { 2419 } else if (op == Token::INIT_CONST) {
2415 // Const initializers need a write barrier. 2420 // Const initializers need a write barrier.
2416 ASSERT(!var->IsParameter()); // No const parameters. 2421 ASSERT(!var->IsParameter()); // No const parameters.
2417 if (var->IsStackLocal()) { 2422 if (var->IsStackLocal()) {
2418 Label skip; 2423 Label skip;
2419 __ mov(edx, StackOperand(var)); 2424 __ mov(edx, StackOperand(var));
2420 __ cmp(edx, isolate()->factory()->the_hole_value()); 2425 __ cmp(edx, isolate()->factory()->the_hole_value());
2421 __ j(not_equal, &skip); 2426 __ j(not_equal, &skip);
2422 __ mov(StackOperand(var), eax); 2427 __ mov(StackOperand(var), eax);
2423 __ bind(&skip); 2428 __ bind(&skip);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 // esp[0] : receiver 2502 // esp[0] : receiver
2498 2503
2499 Property* prop = expr->target()->AsProperty(); 2504 Property* prop = expr->target()->AsProperty();
2500 ASSERT(prop != NULL); 2505 ASSERT(prop != NULL);
2501 ASSERT(prop->key()->AsLiteral() != NULL); 2506 ASSERT(prop->key()->AsLiteral() != NULL);
2502 2507
2503 // Record source code position before IC call. 2508 // Record source code position before IC call.
2504 SetSourcePosition(expr->position()); 2509 SetSourcePosition(expr->position());
2505 __ mov(ecx, prop->key()->AsLiteral()->value()); 2510 __ mov(ecx, prop->key()->AsLiteral()->value());
2506 __ pop(edx); 2511 __ pop(edx);
2507 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2512 CallStoreIC(expr->AssignmentFeedbackId());
2508 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2513 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2509 context()->Plug(eax); 2514 context()->Plug(eax);
2510 } 2515 }
2511 2516
2512 2517
2513 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2518 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2514 // Assignment to a property, using a keyed store IC. 2519 // Assignment to a property, using a keyed store IC.
2515 // eax : value 2520 // eax : value
2516 // esp[0] : key 2521 // esp[0] : key
2517 // esp[kPointerSize] : receiver 2522 // esp[kPointerSize] : receiver
2518 2523
2519 __ pop(ecx); // Key. 2524 __ pop(ecx); // Key.
2520 __ pop(edx); 2525 __ pop(edx);
2521 // Record source code position before IC call. 2526 // Record source code position before IC call.
2522 SetSourcePosition(expr->position()); 2527 SetSourcePosition(expr->position());
2523 Handle<Code> ic = is_classic_mode() 2528 Handle<Code> ic = is_classic_mode()
2524 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2529 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2525 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2530 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2526 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); 2531 CallIC(ic, expr->AssignmentFeedbackId());
2527 2532
2528 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2533 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2529 context()->Plug(eax); 2534 context()->Plug(eax);
2530 } 2535 }
2531 2536
2532 2537
2533 void FullCodeGenerator::VisitProperty(Property* expr) { 2538 void FullCodeGenerator::VisitProperty(Property* expr) {
2534 Comment cmnt(masm_, "[ Property"); 2539 Comment cmnt(masm_, "[ Property");
2535 Expression* key = expr->key(); 2540 Expression* key = expr->key();
2536 2541
2537 if (key->IsPropertyName()) { 2542 if (key->IsPropertyName()) {
2538 VisitForAccumulatorValue(expr->obj()); 2543 VisitForAccumulatorValue(expr->obj());
2539 __ mov(edx, result_register()); 2544 __ mov(edx, result_register());
2540 EmitNamedPropertyLoad(expr); 2545 EmitNamedPropertyLoad(expr);
2541 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2546 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2542 context()->Plug(eax); 2547 context()->Plug(eax);
2543 } else { 2548 } else {
2544 VisitForStackValue(expr->obj()); 2549 VisitForStackValue(expr->obj());
2545 VisitForAccumulatorValue(expr->key()); 2550 VisitForAccumulatorValue(expr->key());
2546 __ pop(edx); // Object. 2551 __ pop(edx); // Object.
2547 __ mov(ecx, result_register()); // Key. 2552 __ mov(ecx, result_register()); // Key.
2548 EmitKeyedPropertyLoad(expr); 2553 EmitKeyedPropertyLoad(expr);
2549 context()->Plug(eax); 2554 context()->Plug(eax);
2550 } 2555 }
2551 } 2556 }
2552 2557
2553 2558
2554 void FullCodeGenerator::CallIC(Handle<Code> code, 2559 void FullCodeGenerator::CallIC(Handle<Code> code,
2555 ContextualMode mode,
2556 TypeFeedbackId ast_id) { 2560 TypeFeedbackId ast_id) {
2557 ic_total_count_++; 2561 ic_total_count_++;
2558 ASSERT(mode != CONTEXTUAL || ast_id.IsNone());
2559 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2562 __ call(code, RelocInfo::CODE_TARGET, ast_id);
2560 } 2563 }
2561 2564
2562 2565
2563 2566
2564 2567
2565 // Code common for calls using the IC. 2568 // Code common for calls using the IC.
2566 void FullCodeGenerator::EmitCallWithIC(Call* expr) { 2569 void FullCodeGenerator::EmitCallWithIC(Call* expr) {
2567 Expression* callee = expr->expression(); 2570 Expression* callee = expr->expression();
2568 ZoneList<Expression*>* args = expr->arguments(); 2571 ZoneList<Expression*>* args = expr->arguments();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2661 int arg_count = args->length(); 2664 int arg_count = args->length();
2662 { PreservePositionScope scope(masm()->positions_recorder()); 2665 { PreservePositionScope scope(masm()->positions_recorder());
2663 for (int i = 0; i < arg_count; i++) { 2666 for (int i = 0; i < arg_count; i++) {
2664 VisitForStackValue(args->at(i)); 2667 VisitForStackValue(args->at(i));
2665 } 2668 }
2666 } 2669 }
2667 // Record source position for debugger. 2670 // Record source position for debugger.
2668 SetSourcePosition(expr->position()); 2671 SetSourcePosition(expr->position());
2669 2672
2670 Handle<Object> uninitialized = 2673 Handle<Object> uninitialized =
2671 TypeFeedbackCells::UninitializedSentinel(isolate()); 2674 TypeFeedbackInfo::UninitializedSentinel(isolate());
2672 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2675 StoreFeedbackVectorSlot(expr->CallFeedbackSlot(), uninitialized);
2673 RecordTypeFeedbackCell(expr->CallFeedbackId(), cell); 2676 __ LoadHeapObject(ebx, FeedbackVector());
2674 __ mov(ebx, cell); 2677 __ mov(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot())));
2675 2678
2676 // Record call targets in unoptimized code. 2679 // Record call targets in unoptimized code.
2677 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); 2680 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET);
2678 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2681 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2679 __ CallStub(&stub, expr->CallFeedbackId()); 2682 __ CallStub(&stub);
2680 2683
2681 RecordJSReturnSite(expr); 2684 RecordJSReturnSite(expr);
2682 // Restore context register. 2685 // Restore context register.
2683 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2686 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2684 context()->DropAndPlug(1, eax); 2687 context()->DropAndPlug(1, eax);
2685 } 2688 }
2686 2689
2687 2690
2688 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2691 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2689 // Push copy of the first argument or undefined if it doesn't exist. 2692 // 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
2841 // Call the construct call builtin that handles allocation and 2844 // Call the construct call builtin that handles allocation and
2842 // constructor invocation. 2845 // constructor invocation.
2843 SetSourcePosition(expr->position()); 2846 SetSourcePosition(expr->position());
2844 2847
2845 // Load function and argument count into edi and eax. 2848 // Load function and argument count into edi and eax.
2846 __ Set(eax, Immediate(arg_count)); 2849 __ Set(eax, Immediate(arg_count));
2847 __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2850 __ mov(edi, Operand(esp, arg_count * kPointerSize));
2848 2851
2849 // Record call targets in unoptimized code. 2852 // Record call targets in unoptimized code.
2850 Handle<Object> uninitialized = 2853 Handle<Object> uninitialized =
2851 TypeFeedbackCells::UninitializedSentinel(isolate()); 2854 TypeFeedbackInfo::UninitializedSentinel(isolate());
2852 Handle<Cell> cell = isolate()->factory()->NewCell(uninitialized); 2855 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized);
2853 RecordTypeFeedbackCell(expr->CallNewFeedbackId(), cell); 2856 __ LoadHeapObject(ebx, FeedbackVector());
2854 __ mov(ebx, cell); 2857 __ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot())));
2855 2858
2856 CallConstructStub stub(RECORD_CALL_TARGET); 2859 CallConstructStub stub(RECORD_CALL_TARGET);
2857 __ call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); 2860 __ call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL);
2858 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2861 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2859 context()->Plug(eax); 2862 context()->Plug(eax);
2860 } 2863 }
2861 2864
2862 2865
2863 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2866 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2864 ZoneList<Expression*>* args = expr->arguments(); 2867 ZoneList<Expression*>* args = expr->arguments();
(...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after
4409 } 4412 }
4410 4413
4411 // Record position before stub call. 4414 // Record position before stub call.
4412 SetSourcePosition(expr->position()); 4415 SetSourcePosition(expr->position());
4413 4416
4414 // Call stub for +1/-1. 4417 // Call stub for +1/-1.
4415 __ bind(&stub_call); 4418 __ bind(&stub_call);
4416 __ mov(edx, eax); 4419 __ mov(edx, eax);
4417 __ mov(eax, Immediate(Smi::FromInt(1))); 4420 __ mov(eax, Immediate(Smi::FromInt(1)));
4418 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); 4421 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE);
4419 CallIC(stub.GetCode(isolate()), 4422 CallIC(stub.GetCode(isolate()), expr->CountBinOpFeedbackId());
4420 NOT_CONTEXTUAL,
4421 expr->CountBinOpFeedbackId());
4422 patch_site.EmitPatchInfo(); 4423 patch_site.EmitPatchInfo();
4423 __ bind(&done); 4424 __ bind(&done);
4424 4425
4425 // Store the value returned in eax. 4426 // Store the value returned in eax.
4426 switch (assign_type) { 4427 switch (assign_type) {
4427 case VARIABLE: 4428 case VARIABLE:
4428 if (expr->is_postfix()) { 4429 if (expr->is_postfix()) {
4429 // Perform the assignment as if via '='. 4430 // Perform the assignment as if via '='.
4430 { EffectContext context(this); 4431 { EffectContext context(this);
4431 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4432 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
(...skipping 10 matching lines...) Expand all
4442 // Perform the assignment as if via '='. 4443 // Perform the assignment as if via '='.
4443 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4444 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4444 Token::ASSIGN); 4445 Token::ASSIGN);
4445 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4446 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4446 context()->Plug(eax); 4447 context()->Plug(eax);
4447 } 4448 }
4448 break; 4449 break;
4449 case NAMED_PROPERTY: { 4450 case NAMED_PROPERTY: {
4450 __ mov(ecx, prop->key()->AsLiteral()->value()); 4451 __ mov(ecx, prop->key()->AsLiteral()->value());
4451 __ pop(edx); 4452 __ pop(edx);
4452 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4453 CallStoreIC(expr->CountStoreFeedbackId());
4453 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4454 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4454 if (expr->is_postfix()) { 4455 if (expr->is_postfix()) {
4455 if (!context()->IsEffect()) { 4456 if (!context()->IsEffect()) {
4456 context()->PlugTOS(); 4457 context()->PlugTOS();
4457 } 4458 }
4458 } else { 4459 } else {
4459 context()->Plug(eax); 4460 context()->Plug(eax);
4460 } 4461 }
4461 break; 4462 break;
4462 } 4463 }
4463 case KEYED_PROPERTY: { 4464 case KEYED_PROPERTY: {
4464 __ pop(ecx); 4465 __ pop(ecx);
4465 __ pop(edx); 4466 __ pop(edx);
4466 Handle<Code> ic = is_classic_mode() 4467 Handle<Code> ic = is_classic_mode()
4467 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4468 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4468 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4469 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4469 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); 4470 CallIC(ic, expr->CountStoreFeedbackId());
4470 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4471 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4471 if (expr->is_postfix()) { 4472 if (expr->is_postfix()) {
4472 // Result is on the stack 4473 // Result is on the stack
4473 if (!context()->IsEffect()) { 4474 if (!context()->IsEffect()) {
4474 context()->PlugTOS(); 4475 context()->PlugTOS();
4475 } 4476 }
4476 } else { 4477 } else {
4477 context()->Plug(eax); 4478 context()->Plug(eax);
4478 } 4479 }
4479 break; 4480 break;
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
4648 __ or_(ecx, eax); 4649 __ or_(ecx, eax);
4649 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4650 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4650 __ cmp(edx, eax); 4651 __ cmp(edx, eax);
4651 Split(cc, if_true, if_false, NULL); 4652 Split(cc, if_true, if_false, NULL);
4652 __ bind(&slow_case); 4653 __ bind(&slow_case);
4653 } 4654 }
4654 4655
4655 // Record position and call the compare IC. 4656 // Record position and call the compare IC.
4656 SetSourcePosition(expr->position()); 4657 SetSourcePosition(expr->position());
4657 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 4658 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
4658 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4659 CallIC(ic, expr->CompareOperationFeedbackId());
4659 patch_site.EmitPatchInfo(); 4660 patch_site.EmitPatchInfo();
4660 4661
4661 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4662 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4662 __ test(eax, eax); 4663 __ test(eax, eax);
4663 Split(cc, if_true, if_false, fall_through); 4664 Split(cc, if_true, if_false, fall_through);
4664 } 4665 }
4665 } 4666 }
4666 4667
4667 // Convert the result of the comparison into one expected for this 4668 // Convert the result of the comparison into one expected for this
4668 // expression's context. 4669 // expression's context.
(...skipping 15 matching lines...) Expand all
4684 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4685 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4685 4686
4686 Handle<Object> nil_value = nil == kNullValue 4687 Handle<Object> nil_value = nil == kNullValue
4687 ? isolate()->factory()->null_value() 4688 ? isolate()->factory()->null_value()
4688 : isolate()->factory()->undefined_value(); 4689 : isolate()->factory()->undefined_value();
4689 if (expr->op() == Token::EQ_STRICT) { 4690 if (expr->op() == Token::EQ_STRICT) {
4690 __ cmp(eax, nil_value); 4691 __ cmp(eax, nil_value);
4691 Split(equal, if_true, if_false, fall_through); 4692 Split(equal, if_true, if_false, fall_through);
4692 } else { 4693 } else {
4693 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4694 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
4694 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); 4695 CallIC(ic, expr->CompareOperationFeedbackId());
4695 __ test(eax, eax); 4696 __ test(eax, eax);
4696 Split(not_zero, if_true, if_false, fall_through); 4697 Split(not_zero, if_true, if_false, fall_through);
4697 } 4698 }
4698 context()->Plug(if_true, if_false); 4699 context()->Plug(if_true, if_false);
4699 } 4700 }
4700 4701
4701 4702
4702 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4703 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4703 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4704 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4704 context()->Plug(eax); 4705 context()->Plug(eax);
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
4912 4913
4913 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4914 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4914 Assembler::target_address_at(call_target_address)); 4915 Assembler::target_address_at(call_target_address));
4915 return OSR_AFTER_STACK_CHECK; 4916 return OSR_AFTER_STACK_CHECK;
4916 } 4917 }
4917 4918
4918 4919
4919 } } // namespace v8::internal 4920 } } // namespace v8::internal
4920 4921
4921 #endif // V8_TARGET_ARCH_IA32 4922 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/debug-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698