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

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

Issue 527093002: Make concrete classes for individual call descriptors. (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
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(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); 1330 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1331 __ mov(LoadConvention::NameRegister(), proxy->var()->name()); 1331 __ mov(LoadDescriptor::NameRegister(), proxy->var()->name());
1332 if (FLAG_vector_ics) { 1332 if (FLAG_vector_ics) {
1333 __ mov(VectorLoadConvention::SlotRegister(), 1333 __ mov(VectorLoadICDescriptor::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(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); 1417 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1418 __ mov(LoadConvention::NameRegister(), var->name()); 1418 __ mov(LoadDescriptor::NameRegister(), var->name());
1419 if (FLAG_vector_ics) { 1419 if (FLAG_vector_ics) {
1420 __ mov(VectorLoadConvention::SlotRegister(), 1420 __ mov(VectorLoadICDescriptor::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(StoreConvention::ValueRegister().is(eax)); 1636 DCHECK(StoreDescriptor::ValueRegister().is(eax));
1637 __ mov(StoreConvention::NameRegister(), Immediate(key->value())); 1637 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value()));
1638 __ mov(StoreConvention::ReceiverRegister(), Operand(esp, 0)); 1638 __ mov(StoreDescriptor::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(LoadConvention::ReceiverRegister(), Operand(esp, 0)); 1817 __ mov(LoadDescriptor::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(LoadConvention::ReceiverRegister(), Operand(esp, kPointerSize)); 1826 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize));
1827 __ mov(LoadConvention::NameRegister(), Operand(esp, 0)); 1827 __ mov(LoadDescriptor::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::kDelegating: { 1959 case Yield::kDelegating: {
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 = LoadConvention::ReceiverRegister(); 1968 Register load_receiver = LoadDescriptor::ReceiverRegister();
1969 Register load_name = LoadConvention::NameRegister(); 1969 Register load_name = LoadDescriptor::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(VectorLoadConvention::SlotRegister(), 2026 __ mov(VectorLoadICDescriptor::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(VectorLoadConvention::SlotRegister(), 2046 __ mov(VectorLoadICDescriptor::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(VectorLoadConvention::SlotRegister(), 2060 __ mov(VectorLoadICDescriptor::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(LoadConvention::NameRegister(), Immediate(key->value())); 2222 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
2223 if (FLAG_vector_ics) { 2223 if (FLAG_vector_ics) {
2224 __ mov(VectorLoadConvention::SlotRegister(), 2224 __ mov(VectorLoadICDescriptor::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(VectorLoadConvention::SlotRegister(), 2237 __ mov(VectorLoadICDescriptor::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(StoreConvention::ReceiverRegister(), eax); 2377 __ Move(StoreDescriptor::ReceiverRegister(), eax);
2378 __ pop(StoreConvention::ValueRegister()); // Restore value. 2378 __ pop(StoreDescriptor::ValueRegister()); // Restore value.
2379 __ mov(StoreConvention::NameRegister(), 2379 __ mov(StoreDescriptor::NameRegister(),
2380 prop->key()->AsLiteral()->value()); 2380 prop->key()->AsLiteral()->value());
2381 CallStoreIC(); 2381 CallStoreIC();
2382 break; 2382 break;
2383 } 2383 }
2384 case KEYED_PROPERTY: { 2384 case KEYED_PROPERTY: {
2385 __ push(eax); // Preserve value. 2385 __ push(eax); // Preserve value.
2386 VisitForStackValue(prop->obj()); 2386 VisitForStackValue(prop->obj());
2387 VisitForAccumulatorValue(prop->key()); 2387 VisitForAccumulatorValue(prop->key());
2388 __ Move(StoreConvention::NameRegister(), eax); 2388 __ Move(StoreDescriptor::NameRegister(), eax);
2389 __ pop(StoreConvention::ReceiverRegister()); // Receiver. 2389 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver.
2390 __ pop(StoreConvention::ValueRegister()); // Restore value. 2390 __ pop(StoreDescriptor::ValueRegister()); // Restore value.
2391 Handle<Code> ic = strict_mode() == SLOPPY 2391 Handle<Code> ic = strict_mode() == SLOPPY
2392 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2392 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2393 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2393 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2394 CallIC(ic); 2394 CallIC(ic);
2395 break; 2395 break;
2396 } 2396 }
2397 } 2397 }
2398 context()->Plug(eax); 2398 context()->Plug(eax);
2399 } 2399 }
2400 2400
2401 2401
2402 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2402 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2403 Variable* var, MemOperand location) { 2403 Variable* var, MemOperand location) {
2404 __ mov(location, eax); 2404 __ mov(location, eax);
2405 if (var->IsContextSlot()) { 2405 if (var->IsContextSlot()) {
2406 __ mov(edx, eax); 2406 __ mov(edx, eax);
2407 int offset = Context::SlotOffset(var->index()); 2407 int offset = Context::SlotOffset(var->index());
2408 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 2408 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
2409 } 2409 }
2410 } 2410 }
2411 2411
2412 2412
2413 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2413 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2414 Token::Value op) { 2414 Token::Value op) {
2415 if (var->IsUnallocated()) { 2415 if (var->IsUnallocated()) {
2416 // Global var, const, or let. 2416 // Global var, const, or let.
2417 __ mov(StoreConvention::NameRegister(), var->name()); 2417 __ mov(StoreDescriptor::NameRegister(), var->name());
2418 __ mov(StoreConvention::ReceiverRegister(), GlobalObjectOperand()); 2418 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
2419 CallStoreIC(); 2419 CallStoreIC();
2420 2420
2421 } else if (op == Token::INIT_CONST_LEGACY) { 2421 } else if (op == Token::INIT_CONST_LEGACY) {
2422 // Const initializers need a write barrier. 2422 // Const initializers need a write barrier.
2423 DCHECK(!var->IsParameter()); // No const parameters. 2423 DCHECK(!var->IsParameter()); // No const parameters.
2424 if (var->IsLookupSlot()) { 2424 if (var->IsLookupSlot()) {
2425 __ push(eax); 2425 __ push(eax);
2426 __ push(esi); 2426 __ push(esi);
2427 __ push(Immediate(var->name())); 2427 __ push(Immediate(var->name()));
2428 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2428 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2481 // Assignment to a property, using a named store IC. 2481 // Assignment to a property, using a named store IC.
2482 // eax : value 2482 // eax : value
2483 // esp[0] : receiver 2483 // esp[0] : receiver
2484 2484
2485 Property* prop = expr->target()->AsProperty(); 2485 Property* prop = expr->target()->AsProperty();
2486 DCHECK(prop != NULL); 2486 DCHECK(prop != NULL);
2487 DCHECK(prop->key()->IsLiteral()); 2487 DCHECK(prop->key()->IsLiteral());
2488 2488
2489 // Record source code position before IC call. 2489 // Record source code position before IC call.
2490 SetSourcePosition(expr->position()); 2490 SetSourcePosition(expr->position());
2491 __ mov(StoreConvention::NameRegister(), prop->key()->AsLiteral()->value()); 2491 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2492 __ pop(StoreConvention::ReceiverRegister()); 2492 __ pop(StoreDescriptor::ReceiverRegister());
2493 CallStoreIC(expr->AssignmentFeedbackId()); 2493 CallStoreIC(expr->AssignmentFeedbackId());
2494 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2494 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2495 context()->Plug(eax); 2495 context()->Plug(eax);
2496 } 2496 }
2497 2497
2498 2498
2499 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2499 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2500 // Assignment to a property, using a keyed store IC. 2500 // Assignment to a property, using a keyed store IC.
2501 // eax : value 2501 // eax : value
2502 // esp[0] : key 2502 // esp[0] : key
2503 // esp[kPointerSize] : receiver 2503 // esp[kPointerSize] : receiver
2504 2504
2505 __ pop(StoreConvention::NameRegister()); // Key. 2505 __ pop(StoreDescriptor::NameRegister()); // Key.
2506 __ pop(StoreConvention::ReceiverRegister()); 2506 __ pop(StoreDescriptor::ReceiverRegister());
2507 DCHECK(StoreConvention::ValueRegister().is(eax)); 2507 DCHECK(StoreDescriptor::ValueRegister().is(eax));
2508 // Record source code position before IC call. 2508 // Record source code position before IC call.
2509 SetSourcePosition(expr->position()); 2509 SetSourcePosition(expr->position());
2510 Handle<Code> ic = strict_mode() == SLOPPY 2510 Handle<Code> ic = strict_mode() == SLOPPY
2511 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2511 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2512 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2512 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2513 CallIC(ic, expr->AssignmentFeedbackId()); 2513 CallIC(ic, expr->AssignmentFeedbackId());
2514 2514
2515 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2515 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2516 context()->Plug(eax); 2516 context()->Plug(eax);
2517 } 2517 }
2518 2518
2519 2519
2520 void FullCodeGenerator::VisitProperty(Property* expr) { 2520 void FullCodeGenerator::VisitProperty(Property* expr) {
2521 Comment cmnt(masm_, "[ Property"); 2521 Comment cmnt(masm_, "[ Property");
2522 Expression* key = expr->key(); 2522 Expression* key = expr->key();
2523 2523
2524 if (key->IsPropertyName()) { 2524 if (key->IsPropertyName()) {
2525 VisitForAccumulatorValue(expr->obj()); 2525 VisitForAccumulatorValue(expr->obj());
2526 __ Move(LoadConvention::ReceiverRegister(), result_register()); 2526 __ Move(LoadDescriptor::ReceiverRegister(), result_register());
2527 EmitNamedPropertyLoad(expr); 2527 EmitNamedPropertyLoad(expr);
2528 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2528 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2529 context()->Plug(eax); 2529 context()->Plug(eax);
2530 } else { 2530 } else {
2531 VisitForStackValue(expr->obj()); 2531 VisitForStackValue(expr->obj());
2532 VisitForAccumulatorValue(expr->key()); 2532 VisitForAccumulatorValue(expr->key());
2533 __ pop(LoadConvention::ReceiverRegister()); // Object. 2533 __ pop(LoadDescriptor::ReceiverRegister()); // Object.
2534 __ Move(LoadConvention::NameRegister(), result_register()); // Key. 2534 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key.
2535 EmitKeyedPropertyLoad(expr); 2535 EmitKeyedPropertyLoad(expr);
2536 context()->Plug(eax); 2536 context()->Plug(eax);
2537 } 2537 }
2538 } 2538 }
2539 2539
2540 2540
2541 void FullCodeGenerator::CallIC(Handle<Code> code, 2541 void FullCodeGenerator::CallIC(Handle<Code> code,
2542 TypeFeedbackId ast_id) { 2542 TypeFeedbackId ast_id) {
2543 ic_total_count_++; 2543 ic_total_count_++;
2544 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2544 __ call(code, RelocInfo::CODE_TARGET, ast_id);
(...skipping 12 matching lines...) Expand all
2557 { StackValueContext context(this); 2557 { StackValueContext context(this);
2558 EmitVariableLoad(callee->AsVariableProxy()); 2558 EmitVariableLoad(callee->AsVariableProxy());
2559 PrepareForBailout(callee, NO_REGISTERS); 2559 PrepareForBailout(callee, NO_REGISTERS);
2560 } 2560 }
2561 // 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
2562 // is a sloppy mode method. 2562 // is a sloppy mode method.
2563 __ push(Immediate(isolate()->factory()->undefined_value())); 2563 __ push(Immediate(isolate()->factory()->undefined_value()));
2564 } else { 2564 } else {
2565 // Load the function from the receiver. 2565 // Load the function from the receiver.
2566 DCHECK(callee->IsProperty()); 2566 DCHECK(callee->IsProperty());
2567 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, 0)); 2567 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2568 EmitNamedPropertyLoad(callee->AsProperty()); 2568 EmitNamedPropertyLoad(callee->AsProperty());
2569 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2569 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2570 // Push the target function under the receiver. 2570 // Push the target function under the receiver.
2571 __ push(Operand(esp, 0)); 2571 __ push(Operand(esp, 0));
2572 __ mov(Operand(esp, kPointerSize), eax); 2572 __ mov(Operand(esp, kPointerSize), eax);
2573 } 2573 }
2574 2574
2575 EmitCall(expr, call_type); 2575 EmitCall(expr, call_type);
2576 } 2576 }
2577 2577
2578 2578
2579 // Code common for calls using the IC. 2579 // Code common for calls using the IC.
2580 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2580 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2581 Expression* key) { 2581 Expression* key) {
2582 // Load the key. 2582 // Load the key.
2583 VisitForAccumulatorValue(key); 2583 VisitForAccumulatorValue(key);
2584 2584
2585 Expression* callee = expr->expression(); 2585 Expression* callee = expr->expression();
2586 2586
2587 // Load the function from the receiver. 2587 // Load the function from the receiver.
2588 DCHECK(callee->IsProperty()); 2588 DCHECK(callee->IsProperty());
2589 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, 0)); 2589 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
2590 __ mov(LoadConvention::NameRegister(), eax); 2590 __ mov(LoadDescriptor::NameRegister(), eax);
2591 EmitKeyedPropertyLoad(callee->AsProperty()); 2591 EmitKeyedPropertyLoad(callee->AsProperty());
2592 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2592 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2593 2593
2594 // Push the target function under the receiver. 2594 // Push the target function under the receiver.
2595 __ push(Operand(esp, 0)); 2595 __ push(Operand(esp, 0));
2596 __ mov(Operand(esp, kPointerSize), eax); 2596 __ mov(Operand(esp, kPointerSize), eax);
2597 2597
2598 EmitCall(expr, CallIC::METHOD); 2598 EmitCall(expr, CallIC::METHOD);
2599 } 2599 }
2600 2600
(...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after
4038 4038
4039 Comment cmnt(masm_, "[ CallRuntime"); 4039 Comment cmnt(masm_, "[ CallRuntime");
4040 ZoneList<Expression*>* args = expr->arguments(); 4040 ZoneList<Expression*>* args = expr->arguments();
4041 4041
4042 if (expr->is_jsruntime()) { 4042 if (expr->is_jsruntime()) {
4043 // Push the builtins object as receiver. 4043 // Push the builtins object as receiver.
4044 __ mov(eax, GlobalObjectOperand()); 4044 __ mov(eax, GlobalObjectOperand());
4045 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 4045 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
4046 4046
4047 // Load the function from the receiver. 4047 // Load the function from the receiver.
4048 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, 0)); 4048 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
4049 __ mov(LoadConvention::NameRegister(), Immediate(expr->name())); 4049 __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
4050 if (FLAG_vector_ics) { 4050 if (FLAG_vector_ics) {
4051 __ mov(VectorLoadConvention::SlotRegister(), 4051 __ mov(VectorLoadICDescriptor::SlotRegister(),
4052 Immediate(Smi::FromInt(expr->CallRuntimeFeedbackSlot()))); 4052 Immediate(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
4053 CallLoadIC(NOT_CONTEXTUAL); 4053 CallLoadIC(NOT_CONTEXTUAL);
4054 } else { 4054 } else {
4055 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); 4055 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
4056 } 4056 }
4057 4057
4058 // Push the target function under the receiver. 4058 // Push the target function under the receiver.
4059 __ push(Operand(esp, 0)); 4059 __ push(Operand(esp, 0));
4060 __ mov(Operand(esp, kPointerSize), eax); 4060 __ mov(Operand(esp, kPointerSize), eax);
4061 4061
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
4228 AccumulatorValueContext context(this); 4228 AccumulatorValueContext context(this);
4229 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4229 EmitVariableLoad(expr->expression()->AsVariableProxy());
4230 } else { 4230 } else {
4231 // Reserve space for result of postfix operation. 4231 // Reserve space for result of postfix operation.
4232 if (expr->is_postfix() && !context()->IsEffect()) { 4232 if (expr->is_postfix() && !context()->IsEffect()) {
4233 __ push(Immediate(Smi::FromInt(0))); 4233 __ push(Immediate(Smi::FromInt(0)));
4234 } 4234 }
4235 if (assign_type == NAMED_PROPERTY) { 4235 if (assign_type == NAMED_PROPERTY) {
4236 // Put the object both on the stack and in the register. 4236 // Put the object both on the stack and in the register.
4237 VisitForStackValue(prop->obj()); 4237 VisitForStackValue(prop->obj());
4238 __ mov(LoadConvention::ReceiverRegister(), Operand(esp, 0)); 4238 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
4239 EmitNamedPropertyLoad(prop); 4239 EmitNamedPropertyLoad(prop);
4240 } else { 4240 } else {
4241 VisitForStackValue(prop->obj()); 4241 VisitForStackValue(prop->obj());
4242 VisitForStackValue(prop->key()); 4242 VisitForStackValue(prop->key());
4243 __ mov(LoadConvention::ReceiverRegister(), 4243 __ mov(LoadDescriptor::ReceiverRegister(),
4244 Operand(esp, kPointerSize)); // Object. 4244 Operand(esp, kPointerSize)); // Object.
4245 __ mov(LoadConvention::NameRegister(), Operand(esp, 0)); // Key. 4245 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key.
4246 EmitKeyedPropertyLoad(prop); 4246 EmitKeyedPropertyLoad(prop);
4247 } 4247 }
4248 } 4248 }
4249 4249
4250 // We need a second deoptimization point after loading the value 4250 // We need a second deoptimization point after loading the value
4251 // in case evaluating the property load my have a side effect. 4251 // in case evaluating the property load my have a side effect.
4252 if (assign_type == VARIABLE) { 4252 if (assign_type == VARIABLE) {
4253 PrepareForBailout(expr->expression(), TOS_REG); 4253 PrepareForBailout(expr->expression(), TOS_REG);
4254 } else { 4254 } else {
4255 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4255 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4350 } 4350 }
4351 } else { 4351 } else {
4352 // Perform the assignment as if via '='. 4352 // Perform the assignment as if via '='.
4353 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4353 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4354 Token::ASSIGN); 4354 Token::ASSIGN);
4355 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4355 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4356 context()->Plug(eax); 4356 context()->Plug(eax);
4357 } 4357 }
4358 break; 4358 break;
4359 case NAMED_PROPERTY: { 4359 case NAMED_PROPERTY: {
4360 __ mov(StoreConvention::NameRegister(), 4360 __ mov(StoreDescriptor::NameRegister(),
4361 prop->key()->AsLiteral()->value()); 4361 prop->key()->AsLiteral()->value());
4362 __ pop(StoreConvention::ReceiverRegister()); 4362 __ pop(StoreDescriptor::ReceiverRegister());
4363 CallStoreIC(expr->CountStoreFeedbackId()); 4363 CallStoreIC(expr->CountStoreFeedbackId());
4364 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4364 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4365 if (expr->is_postfix()) { 4365 if (expr->is_postfix()) {
4366 if (!context()->IsEffect()) { 4366 if (!context()->IsEffect()) {
4367 context()->PlugTOS(); 4367 context()->PlugTOS();
4368 } 4368 }
4369 } else { 4369 } else {
4370 context()->Plug(eax); 4370 context()->Plug(eax);
4371 } 4371 }
4372 break; 4372 break;
4373 } 4373 }
4374 case KEYED_PROPERTY: { 4374 case KEYED_PROPERTY: {
4375 __ pop(StoreConvention::NameRegister()); 4375 __ pop(StoreDescriptor::NameRegister());
4376 __ pop(StoreConvention::ReceiverRegister()); 4376 __ pop(StoreDescriptor::ReceiverRegister());
4377 Handle<Code> ic = strict_mode() == SLOPPY 4377 Handle<Code> ic = strict_mode() == SLOPPY
4378 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4378 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4379 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4379 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4380 CallIC(ic, expr->CountStoreFeedbackId()); 4380 CallIC(ic, expr->CountStoreFeedbackId());
4381 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4381 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4382 if (expr->is_postfix()) { 4382 if (expr->is_postfix()) {
4383 // Result is on the stack 4383 // Result is on the stack
4384 if (!context()->IsEffect()) { 4384 if (!context()->IsEffect()) {
4385 context()->PlugTOS(); 4385 context()->PlugTOS();
4386 } 4386 }
4387 } else { 4387 } else {
4388 context()->Plug(eax); 4388 context()->Plug(eax);
4389 } 4389 }
4390 break; 4390 break;
4391 } 4391 }
4392 } 4392 }
4393 } 4393 }
4394 4394
4395 4395
4396 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4396 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4397 VariableProxy* proxy = expr->AsVariableProxy(); 4397 VariableProxy* proxy = expr->AsVariableProxy();
4398 DCHECK(!context()->IsEffect()); 4398 DCHECK(!context()->IsEffect());
4399 DCHECK(!context()->IsTest()); 4399 DCHECK(!context()->IsTest());
4400 4400
4401 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4401 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4402 Comment cmnt(masm_, "[ Global variable"); 4402 Comment cmnt(masm_, "[ Global variable");
4403 __ mov(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); 4403 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
4404 __ mov(LoadConvention::NameRegister(), Immediate(proxy->name())); 4404 __ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name()));
4405 if (FLAG_vector_ics) { 4405 if (FLAG_vector_ics) {
4406 __ mov(VectorLoadConvention::SlotRegister(), 4406 __ mov(VectorLoadICDescriptor::SlotRegister(),
4407 Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); 4407 Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
4408 } 4408 }
4409 // 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
4410 // error. 4410 // error.
4411 CallLoadIC(NOT_CONTEXTUAL); 4411 CallLoadIC(NOT_CONTEXTUAL);
4412 PrepareForBailout(expr, TOS_REG); 4412 PrepareForBailout(expr, TOS_REG);
4413 context()->Plug(eax); 4413 context()->Plug(eax);
4414 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4414 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4415 Comment cmnt(masm_, "[ Lookup slot"); 4415 Comment cmnt(masm_, "[ Lookup slot");
4416 Label done, slow; 4416 Label done, slow;
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
4826 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4826 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4827 Assembler::target_address_at(call_target_address, 4827 Assembler::target_address_at(call_target_address,
4828 unoptimized_code)); 4828 unoptimized_code));
4829 return OSR_AFTER_STACK_CHECK; 4829 return OSR_AFTER_STACK_CHECK;
4830 } 4830 }
4831 4831
4832 4832
4833 } } // namespace v8::internal 4833 } } // namespace v8::internal
4834 4834
4835 #endif // V8_TARGET_ARCH_IA32 4835 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698