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

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

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

Powered by Google App Engine
This is Rietveld 408576698