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

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

Issue 486213003: Move register conventions out of the IC classes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE. Created 6 years, 3 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/ia32/lithium-codegen-ia32.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 1320 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
1321 __ j(not_equal, slow); 1321 __ j(not_equal, slow);
1322 // Load next context in chain. 1322 // Load next context in chain.
1323 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); 1323 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX));
1324 __ jmp(&next); 1324 __ jmp(&next);
1325 __ bind(&fast); 1325 __ bind(&fast);
1326 } 1326 }
1327 1327
1328 // All extension objects were empty and it is safe to use a global 1328 // All extension objects were empty and it is safe to use a global
1329 // load IC call. 1329 // load IC call.
1330 __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); 1330 __ mov(LoadConvention::ReceiverRegister(), GlobalObjectOperand());
1331 __ mov(LoadIC::NameRegister(), proxy->var()->name()); 1331 __ mov(LoadConvention::NameRegister(), proxy->var()->name());
1332 if (FLAG_vector_ics) { 1332 if (FLAG_vector_ics) {
1333 __ mov(LoadIC::SlotRegister(), 1333 __ mov(VectorLoadConvention::SlotRegister(),
1334 Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); 1334 Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
1335 } 1335 }
1336 1336
1337 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) 1337 ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
1338 ? NOT_CONTEXTUAL 1338 ? NOT_CONTEXTUAL
1339 : CONTEXTUAL; 1339 : CONTEXTUAL;
1340 1340
1341 CallLoadIC(mode); 1341 CallLoadIC(mode);
1342 } 1342 }
1343 1343
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1407 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
1408 // Record position before possible IC call. 1408 // Record position before possible IC call.
1409 SetSourcePosition(proxy->position()); 1409 SetSourcePosition(proxy->position());
1410 Variable* var = proxy->var(); 1410 Variable* var = proxy->var();
1411 1411
1412 // Three cases: global variables, lookup variables, and all other types of 1412 // Three cases: global variables, lookup variables, and all other types of
1413 // variables. 1413 // variables.
1414 switch (var->location()) { 1414 switch (var->location()) {
1415 case Variable::UNALLOCATED: { 1415 case Variable::UNALLOCATED: {
1416 Comment cmnt(masm_, "[ Global variable"); 1416 Comment cmnt(masm_, "[ Global variable");
1417 __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); 1417 __ mov(LoadConvention::ReceiverRegister(), GlobalObjectOperand());
1418 __ mov(LoadIC::NameRegister(), var->name()); 1418 __ mov(LoadConvention::NameRegister(), var->name());
1419 if (FLAG_vector_ics) { 1419 if (FLAG_vector_ics) {
1420 __ mov(LoadIC::SlotRegister(), 1420 __ mov(VectorLoadConvention::SlotRegister(),
1421 Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); 1421 Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
1422 } 1422 }
1423 CallLoadIC(CONTEXTUAL); 1423 CallLoadIC(CONTEXTUAL);
1424 context()->Plug(eax); 1424 context()->Plug(eax);
1425 break; 1425 break;
1426 } 1426 }
1427 1427
1428 case Variable::PARAMETER: 1428 case Variable::PARAMETER:
1429 case Variable::LOCAL: 1429 case Variable::LOCAL:
1430 case Variable::CONTEXT: { 1430 case Variable::CONTEXT: {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1626 switch (property->kind()) { 1626 switch (property->kind()) {
1627 case ObjectLiteral::Property::CONSTANT: 1627 case ObjectLiteral::Property::CONSTANT:
1628 UNREACHABLE(); 1628 UNREACHABLE();
1629 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1629 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1630 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 1630 DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
1631 // Fall through. 1631 // Fall through.
1632 case ObjectLiteral::Property::COMPUTED: 1632 case ObjectLiteral::Property::COMPUTED:
1633 if (key->value()->IsInternalizedString()) { 1633 if (key->value()->IsInternalizedString()) {
1634 if (property->emit_store()) { 1634 if (property->emit_store()) {
1635 VisitForAccumulatorValue(value); 1635 VisitForAccumulatorValue(value);
1636 DCHECK(StoreIC::ValueRegister().is(eax)); 1636 DCHECK(StoreConvention::ValueRegister().is(eax));
1637 __ mov(StoreIC::NameRegister(), Immediate(key->value())); 1637 __ mov(StoreConvention::NameRegister(), Immediate(key->value()));
1638 __ mov(StoreIC::ReceiverRegister(), Operand(esp, 0)); 1638 __ mov(StoreConvention::ReceiverRegister(), Operand(esp, 0));
1639 CallStoreIC(key->LiteralFeedbackId()); 1639 CallStoreIC(key->LiteralFeedbackId());
1640 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1640 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1641 } else { 1641 } else {
1642 VisitForEffect(value); 1642 VisitForEffect(value);
1643 } 1643 }
1644 break; 1644 break;
1645 } 1645 }
1646 __ push(Operand(esp, 0)); // Duplicate receiver. 1646 __ push(Operand(esp, 0)); // Duplicate receiver.
1647 VisitForStackValue(key); 1647 VisitForStackValue(key);
1648 VisitForStackValue(value); 1648 VisitForStackValue(value);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 1807
1808 // Evaluate LHS expression. 1808 // Evaluate LHS expression.
1809 switch (assign_type) { 1809 switch (assign_type) {
1810 case VARIABLE: 1810 case VARIABLE:
1811 // Nothing to do here. 1811 // Nothing to do here.
1812 break; 1812 break;
1813 case NAMED_PROPERTY: 1813 case NAMED_PROPERTY:
1814 if (expr->is_compound()) { 1814 if (expr->is_compound()) {
1815 // We need the receiver both on the stack and in the register. 1815 // We need the receiver both on the stack and in the register.
1816 VisitForStackValue(property->obj()); 1816 VisitForStackValue(property->obj());
1817 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); 1817 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, 0));
1818 } else { 1818 } else {
1819 VisitForStackValue(property->obj()); 1819 VisitForStackValue(property->obj());
1820 } 1820 }
1821 break; 1821 break;
1822 case KEYED_PROPERTY: { 1822 case KEYED_PROPERTY: {
1823 if (expr->is_compound()) { 1823 if (expr->is_compound()) {
1824 VisitForStackValue(property->obj()); 1824 VisitForStackValue(property->obj());
1825 VisitForStackValue(property->key()); 1825 VisitForStackValue(property->key());
1826 __ mov(LoadIC::ReceiverRegister(), Operand(esp, kPointerSize)); 1826 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, kPointerSize));
1827 __ mov(LoadIC::NameRegister(), Operand(esp, 0)); 1827 __ mov(LoadConvention::NameRegister(), Operand(esp, 0));
1828 } else { 1828 } else {
1829 VisitForStackValue(property->obj()); 1829 VisitForStackValue(property->obj());
1830 VisitForStackValue(property->key()); 1830 VisitForStackValue(property->key());
1831 } 1831 }
1832 break; 1832 break;
1833 } 1833 }
1834 } 1834 }
1835 1835
1836 // For compound assignments we need another deoptimization point after the 1836 // For compound assignments we need another deoptimization point after the
1837 // variable/property load. 1837 // variable/property load.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1958 1958
1959 case Yield::DELEGATING: { 1959 case Yield::DELEGATING: {
1960 VisitForStackValue(expr->generator_object()); 1960 VisitForStackValue(expr->generator_object());
1961 1961
1962 // Initial stack layout is as follows: 1962 // Initial stack layout is as follows:
1963 // [sp + 1 * kPointerSize] iter 1963 // [sp + 1 * kPointerSize] iter
1964 // [sp + 0 * kPointerSize] g 1964 // [sp + 0 * kPointerSize] g
1965 1965
1966 Label l_catch, l_try, l_suspend, l_continuation, l_resume; 1966 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
1967 Label l_next, l_call, l_loop; 1967 Label l_next, l_call, l_loop;
1968 Register load_receiver = LoadIC::ReceiverRegister(); 1968 Register load_receiver = LoadConvention::ReceiverRegister();
1969 Register load_name = LoadIC::NameRegister(); 1969 Register load_name = LoadConvention::NameRegister();
1970 1970
1971 // Initial send value is undefined. 1971 // Initial send value is undefined.
1972 __ mov(eax, isolate()->factory()->undefined_value()); 1972 __ mov(eax, isolate()->factory()->undefined_value());
1973 __ jmp(&l_next); 1973 __ jmp(&l_next);
1974 1974
1975 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 1975 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
1976 __ bind(&l_catch); 1976 __ bind(&l_catch);
1977 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 1977 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
1978 __ mov(load_name, isolate()->factory()->throw_string()); // "throw" 1978 __ mov(load_name, isolate()->factory()->throw_string()); // "throw"
1979 __ push(load_name); // "throw" 1979 __ push(load_name); // "throw"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2016 2016
2017 __ mov(load_name, isolate()->factory()->next_string()); 2017 __ mov(load_name, isolate()->factory()->next_string());
2018 __ push(load_name); // "next" 2018 __ push(load_name); // "next"
2019 __ push(Operand(esp, 2 * kPointerSize)); // iter 2019 __ push(Operand(esp, 2 * kPointerSize)); // iter
2020 __ push(eax); // received 2020 __ push(eax); // received
2021 2021
2022 // result = receiver[f](arg); 2022 // result = receiver[f](arg);
2023 __ bind(&l_call); 2023 __ bind(&l_call);
2024 __ mov(load_receiver, Operand(esp, kPointerSize)); 2024 __ mov(load_receiver, Operand(esp, kPointerSize));
2025 if (FLAG_vector_ics) { 2025 if (FLAG_vector_ics) {
2026 __ mov(LoadIC::SlotRegister(), 2026 __ mov(VectorLoadConvention::SlotRegister(),
2027 Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); 2027 Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
2028 } 2028 }
2029 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2029 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2030 CallIC(ic, TypeFeedbackId::None()); 2030 CallIC(ic, TypeFeedbackId::None());
2031 __ mov(edi, eax); 2031 __ mov(edi, eax);
2032 __ mov(Operand(esp, 2 * kPointerSize), edi); 2032 __ mov(Operand(esp, 2 * kPointerSize), edi);
2033 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); 2033 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
2034 __ CallStub(&stub); 2034 __ CallStub(&stub);
2035 2035
2036 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2036 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2037 __ Drop(1); // The function is still on the stack; drop it. 2037 __ Drop(1); // The function is still on the stack; drop it.
2038 2038
2039 // if (!result.done) goto l_try; 2039 // if (!result.done) goto l_try;
2040 __ bind(&l_loop); 2040 __ bind(&l_loop);
2041 __ push(eax); // save result 2041 __ push(eax); // save result
2042 __ Move(load_receiver, eax); // result 2042 __ Move(load_receiver, eax); // result
2043 __ mov(load_name, 2043 __ mov(load_name,
2044 isolate()->factory()->done_string()); // "done" 2044 isolate()->factory()->done_string()); // "done"
2045 if (FLAG_vector_ics) { 2045 if (FLAG_vector_ics) {
2046 __ mov(LoadIC::SlotRegister(), 2046 __ mov(VectorLoadConvention::SlotRegister(),
2047 Immediate(Smi::FromInt(expr->DoneFeedbackSlot()))); 2047 Immediate(Smi::FromInt(expr->DoneFeedbackSlot())));
2048 } 2048 }
2049 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax 2049 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
2050 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2050 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2051 CallIC(bool_ic); 2051 CallIC(bool_ic);
2052 __ test(eax, eax); 2052 __ test(eax, eax);
2053 __ j(zero, &l_try); 2053 __ j(zero, &l_try);
2054 2054
2055 // result.value 2055 // result.value
2056 __ pop(load_receiver); // result 2056 __ pop(load_receiver); // result
2057 __ mov(load_name, 2057 __ mov(load_name,
2058 isolate()->factory()->value_string()); // "value" 2058 isolate()->factory()->value_string()); // "value"
2059 if (FLAG_vector_ics) { 2059 if (FLAG_vector_ics) {
2060 __ mov(LoadIC::SlotRegister(), 2060 __ mov(VectorLoadConvention::SlotRegister(),
2061 Immediate(Smi::FromInt(expr->ValueFeedbackSlot()))); 2061 Immediate(Smi::FromInt(expr->ValueFeedbackSlot())));
2062 } 2062 }
2063 CallLoadIC(NOT_CONTEXTUAL); // result.value in eax 2063 CallLoadIC(NOT_CONTEXTUAL); // result.value in eax
2064 context()->DropAndPlug(2, eax); // drop iter and g 2064 context()->DropAndPlug(2, eax); // drop iter and g
2065 break; 2065 break;
2066 } 2066 }
2067 } 2067 }
2068 } 2068 }
2069 2069
2070 2070
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2212 // root set. 2212 // root set.
2213 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, 2213 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset,
2214 ecx, edx, kDontSaveFPRegs); 2214 ecx, edx, kDontSaveFPRegs);
2215 } 2215 }
2216 2216
2217 2217
2218 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2218 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2219 SetSourcePosition(prop->position()); 2219 SetSourcePosition(prop->position());
2220 Literal* key = prop->key()->AsLiteral(); 2220 Literal* key = prop->key()->AsLiteral();
2221 DCHECK(!key->value()->IsSmi()); 2221 DCHECK(!key->value()->IsSmi());
2222 __ mov(LoadIC::NameRegister(), Immediate(key->value())); 2222 __ mov(LoadConvention::NameRegister(), Immediate(key->value()));
2223 if (FLAG_vector_ics) { 2223 if (FLAG_vector_ics) {
2224 __ mov(LoadIC::SlotRegister(), 2224 __ mov(VectorLoadConvention::SlotRegister(),
2225 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); 2225 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot())));
2226 CallLoadIC(NOT_CONTEXTUAL); 2226 CallLoadIC(NOT_CONTEXTUAL);
2227 } else { 2227 } else {
2228 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2228 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2229 } 2229 }
2230 } 2230 }
2231 2231
2232 2232
2233 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2233 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2234 SetSourcePosition(prop->position()); 2234 SetSourcePosition(prop->position());
2235 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2235 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2236 if (FLAG_vector_ics) { 2236 if (FLAG_vector_ics) {
2237 __ mov(LoadIC::SlotRegister(), 2237 __ mov(VectorLoadConvention::SlotRegister(),
2238 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); 2238 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot())));
2239 CallIC(ic); 2239 CallIC(ic);
2240 } else { 2240 } else {
2241 CallIC(ic, prop->PropertyFeedbackId()); 2241 CallIC(ic, prop->PropertyFeedbackId());
2242 } 2242 }
2243 } 2243 }
2244 2244
2245 2245
2246 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2246 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2247 Token::Value op, 2247 Token::Value op,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
2367 switch (assign_type) { 2367 switch (assign_type) {
2368 case VARIABLE: { 2368 case VARIABLE: {
2369 Variable* var = expr->AsVariableProxy()->var(); 2369 Variable* var = expr->AsVariableProxy()->var();
2370 EffectContext context(this); 2370 EffectContext context(this);
2371 EmitVariableAssignment(var, Token::ASSIGN); 2371 EmitVariableAssignment(var, Token::ASSIGN);
2372 break; 2372 break;
2373 } 2373 }
2374 case NAMED_PROPERTY: { 2374 case NAMED_PROPERTY: {
2375 __ push(eax); // Preserve value. 2375 __ push(eax); // Preserve value.
2376 VisitForAccumulatorValue(prop->obj()); 2376 VisitForAccumulatorValue(prop->obj());
2377 __ Move(StoreIC::ReceiverRegister(), eax); 2377 __ Move(StoreConvention::ReceiverRegister(), eax);
2378 __ pop(StoreIC::ValueRegister()); // Restore value. 2378 __ pop(StoreConvention::ValueRegister()); // Restore value.
2379 __ mov(StoreIC::NameRegister(), prop->key()->AsLiteral()->value()); 2379 __ mov(StoreConvention::NameRegister(),
2380 prop->key()->AsLiteral()->value());
2380 CallStoreIC(); 2381 CallStoreIC();
2381 break; 2382 break;
2382 } 2383 }
2383 case KEYED_PROPERTY: { 2384 case KEYED_PROPERTY: {
2384 __ push(eax); // Preserve value. 2385 __ push(eax); // Preserve value.
2385 VisitForStackValue(prop->obj()); 2386 VisitForStackValue(prop->obj());
2386 VisitForAccumulatorValue(prop->key()); 2387 VisitForAccumulatorValue(prop->key());
2387 __ Move(KeyedStoreIC::NameRegister(), eax); 2388 __ Move(StoreConvention::NameRegister(), eax);
2388 __ pop(KeyedStoreIC::ReceiverRegister()); // Receiver. 2389 __ pop(StoreConvention::ReceiverRegister()); // Receiver.
2389 __ pop(KeyedStoreIC::ValueRegister()); // Restore value. 2390 __ pop(StoreConvention::ValueRegister()); // Restore value.
2390 Handle<Code> ic = strict_mode() == SLOPPY 2391 Handle<Code> ic = strict_mode() == SLOPPY
2391 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2392 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2392 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2393 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2393 CallIC(ic); 2394 CallIC(ic);
2394 break; 2395 break;
2395 } 2396 }
2396 } 2397 }
2397 context()->Plug(eax); 2398 context()->Plug(eax);
2398 } 2399 }
2399 2400
2400 2401
2401 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2402 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2402 Variable* var, MemOperand location) { 2403 Variable* var, MemOperand location) {
2403 __ mov(location, eax); 2404 __ mov(location, eax);
2404 if (var->IsContextSlot()) { 2405 if (var->IsContextSlot()) {
2405 __ mov(edx, eax); 2406 __ mov(edx, eax);
2406 int offset = Context::SlotOffset(var->index()); 2407 int offset = Context::SlotOffset(var->index());
2407 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 2408 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
2408 } 2409 }
2409 } 2410 }
2410 2411
2411 2412
2412 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2413 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2413 Token::Value op) { 2414 Token::Value op) {
2414 if (var->IsUnallocated()) { 2415 if (var->IsUnallocated()) {
2415 // Global var, const, or let. 2416 // Global var, const, or let.
2416 __ mov(StoreIC::NameRegister(), var->name()); 2417 __ mov(StoreConvention::NameRegister(), var->name());
2417 __ mov(StoreIC::ReceiverRegister(), GlobalObjectOperand()); 2418 __ mov(StoreConvention::ReceiverRegister(), GlobalObjectOperand());
2418 CallStoreIC(); 2419 CallStoreIC();
2419 2420
2420 } else if (op == Token::INIT_CONST_LEGACY) { 2421 } else if (op == Token::INIT_CONST_LEGACY) {
2421 // Const initializers need a write barrier. 2422 // Const initializers need a write barrier.
2422 DCHECK(!var->IsParameter()); // No const parameters. 2423 DCHECK(!var->IsParameter()); // No const parameters.
2423 if (var->IsLookupSlot()) { 2424 if (var->IsLookupSlot()) {
2424 __ push(eax); 2425 __ push(eax);
2425 __ push(esi); 2426 __ push(esi);
2426 __ push(Immediate(var->name())); 2427 __ push(Immediate(var->name()));
2427 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2428 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2480 // Assignment to a property, using a named store IC. 2481 // Assignment to a property, using a named store IC.
2481 // eax : value 2482 // eax : value
2482 // esp[0] : receiver 2483 // esp[0] : receiver
2483 2484
2484 Property* prop = expr->target()->AsProperty(); 2485 Property* prop = expr->target()->AsProperty();
2485 DCHECK(prop != NULL); 2486 DCHECK(prop != NULL);
2486 DCHECK(prop->key()->IsLiteral()); 2487 DCHECK(prop->key()->IsLiteral());
2487 2488
2488 // Record source code position before IC call. 2489 // Record source code position before IC call.
2489 SetSourcePosition(expr->position()); 2490 SetSourcePosition(expr->position());
2490 __ mov(StoreIC::NameRegister(), prop->key()->AsLiteral()->value()); 2491 __ mov(StoreConvention::NameRegister(), prop->key()->AsLiteral()->value());
2491 __ pop(StoreIC::ReceiverRegister()); 2492 __ pop(StoreConvention::ReceiverRegister());
2492 CallStoreIC(expr->AssignmentFeedbackId()); 2493 CallStoreIC(expr->AssignmentFeedbackId());
2493 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2494 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2494 context()->Plug(eax); 2495 context()->Plug(eax);
2495 } 2496 }
2496 2497
2497 2498
2498 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2499 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2499 // Assignment to a property, using a keyed store IC. 2500 // Assignment to a property, using a keyed store IC.
2500 // eax : value 2501 // eax : value
2501 // esp[0] : key 2502 // esp[0] : key
2502 // esp[kPointerSize] : receiver 2503 // esp[kPointerSize] : receiver
2503 2504
2504 __ pop(KeyedStoreIC::NameRegister()); // Key. 2505 __ pop(StoreConvention::NameRegister()); // Key.
2505 __ pop(KeyedStoreIC::ReceiverRegister()); 2506 __ pop(StoreConvention::ReceiverRegister());
2506 DCHECK(KeyedStoreIC::ValueRegister().is(eax)); 2507 DCHECK(StoreConvention::ValueRegister().is(eax));
2507 // Record source code position before IC call. 2508 // Record source code position before IC call.
2508 SetSourcePosition(expr->position()); 2509 SetSourcePosition(expr->position());
2509 Handle<Code> ic = strict_mode() == SLOPPY 2510 Handle<Code> ic = strict_mode() == SLOPPY
2510 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2511 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2511 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2512 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2512 CallIC(ic, expr->AssignmentFeedbackId()); 2513 CallIC(ic, expr->AssignmentFeedbackId());
2513 2514
2514 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2515 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2515 context()->Plug(eax); 2516 context()->Plug(eax);
2516 } 2517 }
2517 2518
2518 2519
2519 void FullCodeGenerator::VisitProperty(Property* expr) { 2520 void FullCodeGenerator::VisitProperty(Property* expr) {
2520 Comment cmnt(masm_, "[ Property"); 2521 Comment cmnt(masm_, "[ Property");
2521 Expression* key = expr->key(); 2522 Expression* key = expr->key();
2522 2523
2523 if (key->IsPropertyName()) { 2524 if (key->IsPropertyName()) {
2524 VisitForAccumulatorValue(expr->obj()); 2525 VisitForAccumulatorValue(expr->obj());
2525 __ Move(LoadIC::ReceiverRegister(), result_register()); 2526 __ Move(LoadConvention::ReceiverRegister(), result_register());
2526 EmitNamedPropertyLoad(expr); 2527 EmitNamedPropertyLoad(expr);
2527 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2528 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2528 context()->Plug(eax); 2529 context()->Plug(eax);
2529 } else { 2530 } else {
2530 VisitForStackValue(expr->obj()); 2531 VisitForStackValue(expr->obj());
2531 VisitForAccumulatorValue(expr->key()); 2532 VisitForAccumulatorValue(expr->key());
2532 __ pop(LoadIC::ReceiverRegister()); // Object. 2533 __ pop(LoadConvention::ReceiverRegister()); // Object.
2533 __ Move(LoadIC::NameRegister(), result_register()); // Key. 2534 __ Move(LoadConvention::NameRegister(), result_register()); // Key.
2534 EmitKeyedPropertyLoad(expr); 2535 EmitKeyedPropertyLoad(expr);
2535 context()->Plug(eax); 2536 context()->Plug(eax);
2536 } 2537 }
2537 } 2538 }
2538 2539
2539 2540
2540 void FullCodeGenerator::CallIC(Handle<Code> code, 2541 void FullCodeGenerator::CallIC(Handle<Code> code,
2541 TypeFeedbackId ast_id) { 2542 TypeFeedbackId ast_id) {
2542 ic_total_count_++; 2543 ic_total_count_++;
2543 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2544 __ call(code, RelocInfo::CODE_TARGET, ast_id);
(...skipping 12 matching lines...) Expand all
2556 { StackValueContext context(this); 2557 { StackValueContext context(this);
2557 EmitVariableLoad(callee->AsVariableProxy()); 2558 EmitVariableLoad(callee->AsVariableProxy());
2558 PrepareForBailout(callee, NO_REGISTERS); 2559 PrepareForBailout(callee, NO_REGISTERS);
2559 } 2560 }
2560 // Push undefined as receiver. This is patched in the method prologue if it 2561 // Push undefined as receiver. This is patched in the method prologue if it
2561 // is a sloppy mode method. 2562 // is a sloppy mode method.
2562 __ push(Immediate(isolate()->factory()->undefined_value())); 2563 __ push(Immediate(isolate()->factory()->undefined_value()));
2563 } else { 2564 } else {
2564 // Load the function from the receiver. 2565 // Load the function from the receiver.
2565 DCHECK(callee->IsProperty()); 2566 DCHECK(callee->IsProperty());
2566 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); 2567 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, 0));
2567 EmitNamedPropertyLoad(callee->AsProperty()); 2568 EmitNamedPropertyLoad(callee->AsProperty());
2568 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2569 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2569 // Push the target function under the receiver. 2570 // Push the target function under the receiver.
2570 __ push(Operand(esp, 0)); 2571 __ push(Operand(esp, 0));
2571 __ mov(Operand(esp, kPointerSize), eax); 2572 __ mov(Operand(esp, kPointerSize), eax);
2572 } 2573 }
2573 2574
2574 EmitCall(expr, call_type); 2575 EmitCall(expr, call_type);
2575 } 2576 }
2576 2577
2577 2578
2578 // Code common for calls using the IC. 2579 // Code common for calls using the IC.
2579 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2580 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2580 Expression* key) { 2581 Expression* key) {
2581 // Load the key. 2582 // Load the key.
2582 VisitForAccumulatorValue(key); 2583 VisitForAccumulatorValue(key);
2583 2584
2584 Expression* callee = expr->expression(); 2585 Expression* callee = expr->expression();
2585 2586
2586 // Load the function from the receiver. 2587 // Load the function from the receiver.
2587 DCHECK(callee->IsProperty()); 2588 DCHECK(callee->IsProperty());
2588 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); 2589 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, 0));
2589 __ mov(LoadIC::NameRegister(), eax); 2590 __ mov(LoadConvention::NameRegister(), eax);
2590 EmitKeyedPropertyLoad(callee->AsProperty()); 2591 EmitKeyedPropertyLoad(callee->AsProperty());
2591 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2592 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2592 2593
2593 // Push the target function under the receiver. 2594 // Push the target function under the receiver.
2594 __ push(Operand(esp, 0)); 2595 __ push(Operand(esp, 0));
2595 __ mov(Operand(esp, kPointerSize), eax); 2596 __ mov(Operand(esp, kPointerSize), eax);
2596 2597
2597 EmitCall(expr, CallIC::METHOD); 2598 EmitCall(expr, CallIC::METHOD);
2598 } 2599 }
2599 2600
(...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after
4037 4038
4038 Comment cmnt(masm_, "[ CallRuntime"); 4039 Comment cmnt(masm_, "[ CallRuntime");
4039 ZoneList<Expression*>* args = expr->arguments(); 4040 ZoneList<Expression*>* args = expr->arguments();
4040 4041
4041 if (expr->is_jsruntime()) { 4042 if (expr->is_jsruntime()) {
4042 // Push the builtins object as receiver. 4043 // Push the builtins object as receiver.
4043 __ mov(eax, GlobalObjectOperand()); 4044 __ mov(eax, GlobalObjectOperand());
4044 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 4045 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
4045 4046
4046 // Load the function from the receiver. 4047 // Load the function from the receiver.
4047 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); 4048 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, 0));
4048 __ mov(LoadIC::NameRegister(), Immediate(expr->name())); 4049 __ mov(LoadConvention::NameRegister(), Immediate(expr->name()));
4049 if (FLAG_vector_ics) { 4050 if (FLAG_vector_ics) {
4050 __ mov(LoadIC::SlotRegister(), 4051 __ mov(VectorLoadConvention::SlotRegister(),
4051 Immediate(Smi::FromInt(expr->CallRuntimeFeedbackSlot()))); 4052 Immediate(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
4052 CallLoadIC(NOT_CONTEXTUAL); 4053 CallLoadIC(NOT_CONTEXTUAL);
4053 } else { 4054 } else {
4054 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); 4055 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
4055 } 4056 }
4056 4057
4057 // Push the target function under the receiver. 4058 // Push the target function under the receiver.
4058 __ push(Operand(esp, 0)); 4059 __ push(Operand(esp, 0));
4059 __ mov(Operand(esp, kPointerSize), eax); 4060 __ mov(Operand(esp, kPointerSize), eax);
4060 4061
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
4227 AccumulatorValueContext context(this); 4228 AccumulatorValueContext context(this);
4228 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4229 EmitVariableLoad(expr->expression()->AsVariableProxy());
4229 } else { 4230 } else {
4230 // Reserve space for result of postfix operation. 4231 // Reserve space for result of postfix operation.
4231 if (expr->is_postfix() && !context()->IsEffect()) { 4232 if (expr->is_postfix() && !context()->IsEffect()) {
4232 __ push(Immediate(Smi::FromInt(0))); 4233 __ push(Immediate(Smi::FromInt(0)));
4233 } 4234 }
4234 if (assign_type == NAMED_PROPERTY) { 4235 if (assign_type == NAMED_PROPERTY) {
4235 // Put the object both on the stack and in the register. 4236 // Put the object both on the stack and in the register.
4236 VisitForStackValue(prop->obj()); 4237 VisitForStackValue(prop->obj());
4237 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); 4238 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, 0));
4238 EmitNamedPropertyLoad(prop); 4239 EmitNamedPropertyLoad(prop);
4239 } else { 4240 } else {
4240 VisitForStackValue(prop->obj()); 4241 VisitForStackValue(prop->obj());
4241 VisitForStackValue(prop->key()); 4242 VisitForStackValue(prop->key());
4242 __ mov(LoadIC::ReceiverRegister(), 4243 __ mov(LoadConvention::ReceiverRegister(),
4243 Operand(esp, kPointerSize)); // Object. 4244 Operand(esp, kPointerSize)); // Object.
4244 __ mov(LoadIC::NameRegister(), Operand(esp, 0)); // Key. 4245 __ mov(LoadConvention::NameRegister(), Operand(esp, 0)); // Key.
4245 EmitKeyedPropertyLoad(prop); 4246 EmitKeyedPropertyLoad(prop);
4246 } 4247 }
4247 } 4248 }
4248 4249
4249 // We need a second deoptimization point after loading the value 4250 // We need a second deoptimization point after loading the value
4250 // in case evaluating the property load my have a side effect. 4251 // in case evaluating the property load my have a side effect.
4251 if (assign_type == VARIABLE) { 4252 if (assign_type == VARIABLE) {
4252 PrepareForBailout(expr->expression(), TOS_REG); 4253 PrepareForBailout(expr->expression(), TOS_REG);
4253 } else { 4254 } else {
4254 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4255 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4349 } 4350 }
4350 } else { 4351 } else {
4351 // Perform the assignment as if via '='. 4352 // Perform the assignment as if via '='.
4352 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4353 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4353 Token::ASSIGN); 4354 Token::ASSIGN);
4354 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4355 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4355 context()->Plug(eax); 4356 context()->Plug(eax);
4356 } 4357 }
4357 break; 4358 break;
4358 case NAMED_PROPERTY: { 4359 case NAMED_PROPERTY: {
4359 __ mov(StoreIC::NameRegister(), prop->key()->AsLiteral()->value()); 4360 __ mov(StoreConvention::NameRegister(),
4360 __ pop(StoreIC::ReceiverRegister()); 4361 prop->key()->AsLiteral()->value());
4362 __ pop(StoreConvention::ReceiverRegister());
4361 CallStoreIC(expr->CountStoreFeedbackId()); 4363 CallStoreIC(expr->CountStoreFeedbackId());
4362 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4364 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4363 if (expr->is_postfix()) { 4365 if (expr->is_postfix()) {
4364 if (!context()->IsEffect()) { 4366 if (!context()->IsEffect()) {
4365 context()->PlugTOS(); 4367 context()->PlugTOS();
4366 } 4368 }
4367 } else { 4369 } else {
4368 context()->Plug(eax); 4370 context()->Plug(eax);
4369 } 4371 }
4370 break; 4372 break;
4371 } 4373 }
4372 case KEYED_PROPERTY: { 4374 case KEYED_PROPERTY: {
4373 __ pop(KeyedStoreIC::NameRegister()); 4375 __ pop(StoreConvention::NameRegister());
4374 __ pop(KeyedStoreIC::ReceiverRegister()); 4376 __ pop(StoreConvention::ReceiverRegister());
4375 Handle<Code> ic = strict_mode() == SLOPPY 4377 Handle<Code> ic = strict_mode() == SLOPPY
4376 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4378 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4377 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4379 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4378 CallIC(ic, expr->CountStoreFeedbackId()); 4380 CallIC(ic, expr->CountStoreFeedbackId());
4379 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4381 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4380 if (expr->is_postfix()) { 4382 if (expr->is_postfix()) {
4381 // Result is on the stack 4383 // Result is on the stack
4382 if (!context()->IsEffect()) { 4384 if (!context()->IsEffect()) {
4383 context()->PlugTOS(); 4385 context()->PlugTOS();
4384 } 4386 }
4385 } else { 4387 } else {
4386 context()->Plug(eax); 4388 context()->Plug(eax);
4387 } 4389 }
4388 break; 4390 break;
4389 } 4391 }
4390 } 4392 }
4391 } 4393 }
4392 4394
4393 4395
4394 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4396 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4395 VariableProxy* proxy = expr->AsVariableProxy(); 4397 VariableProxy* proxy = expr->AsVariableProxy();
4396 DCHECK(!context()->IsEffect()); 4398 DCHECK(!context()->IsEffect());
4397 DCHECK(!context()->IsTest()); 4399 DCHECK(!context()->IsTest());
4398 4400
4399 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4401 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4400 Comment cmnt(masm_, "[ Global variable"); 4402 Comment cmnt(masm_, "[ Global variable");
4401 __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); 4403 __ mov(LoadConvention::ReceiverRegister(), GlobalObjectOperand());
4402 __ mov(LoadIC::NameRegister(), Immediate(proxy->name())); 4404 __ mov(LoadConvention::NameRegister(), Immediate(proxy->name()));
4403 if (FLAG_vector_ics) { 4405 if (FLAG_vector_ics) {
4404 __ mov(LoadIC::SlotRegister(), 4406 __ mov(VectorLoadConvention::SlotRegister(),
4405 Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); 4407 Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
4406 } 4408 }
4407 // Use a regular load, not a contextual load, to avoid a reference 4409 // Use a regular load, not a contextual load, to avoid a reference
4408 // error. 4410 // error.
4409 CallLoadIC(NOT_CONTEXTUAL); 4411 CallLoadIC(NOT_CONTEXTUAL);
4410 PrepareForBailout(expr, TOS_REG); 4412 PrepareForBailout(expr, TOS_REG);
4411 context()->Plug(eax); 4413 context()->Plug(eax);
4412 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4414 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4413 Comment cmnt(masm_, "[ Lookup slot"); 4415 Comment cmnt(masm_, "[ Lookup slot");
4414 Label done, slow; 4416 Label done, slow;
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
4824 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4826 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4825 Assembler::target_address_at(call_target_address, 4827 Assembler::target_address_at(call_target_address,
4826 unoptimized_code)); 4828 unoptimized_code));
4827 return OSR_AFTER_STACK_CHECK; 4829 return OSR_AFTER_STACK_CHECK;
4828 } 4830 }
4829 4831
4830 4832
4831 } } // namespace v8::internal 4833 } } // namespace v8::internal
4832 4834
4833 #endif // V8_TARGET_ARCH_IA32 4835 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/debug-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698