diff options
author | Fedor Indutny <fedor@indutny.com> | 2014-10-10 14:49:02 +0400 |
---|---|---|
committer | Fedor Indutny <fedor@indutny.com> | 2014-10-10 14:49:02 +0400 |
commit | 6bcea4ff932144a5fd02affefd45164fbf471e67 (patch) | |
tree | a8e078c679b12f0daebe10ed254239cb0d79e146 /deps/v8/src/ia32/full-codegen-ia32.cc | |
parent | 4fae2356d105e394115188a814097c4a95ae0c5d (diff) | |
download | node-new-6bcea4ff932144a5fd02affefd45164fbf471e67.tar.gz |
deps: update v8 to 3.29.93.1
Diffstat (limited to 'deps/v8/src/ia32/full-codegen-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/full-codegen-ia32.cc | 352 |
1 files changed, 239 insertions, 113 deletions
diff --git a/deps/v8/src/ia32/full-codegen-ia32.cc b/deps/v8/src/ia32/full-codegen-ia32.cc index aacaeeb6a6..a382dad315 100644 --- a/deps/v8/src/ia32/full-codegen-ia32.cc +++ b/deps/v8/src/ia32/full-codegen-ia32.cc @@ -6,15 +6,16 @@ #if V8_TARGET_ARCH_IA32 +#include "src/code-factory.h" #include "src/code-stubs.h" #include "src/codegen.h" #include "src/compiler.h" #include "src/debug.h" #include "src/full-codegen.h" +#include "src/ic/ic.h" #include "src/isolate-inl.h" #include "src/parser.h" #include "src/scopes.h" -#include "src/stub-cache.h" namespace v8 { namespace internal { @@ -988,7 +989,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { // Record position before stub call for type feedback. SetSourcePosition(clause->position()); - Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); + Handle<Code> ic = + CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); CallIC(ic, clause->CompareId()); patch_site.EmitPatchInfo(); @@ -1116,7 +1118,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // No need for a write barrier, we are storing a Smi in the feedback vector. __ LoadHeapObject(ebx, FeedbackVector()); __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)), - Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate()))); + Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate()))); __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object @@ -1255,9 +1257,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, !pretenure && scope()->is_function_scope() && info->num_literals() == 0) { - FastNewClosureStub stub(isolate(), - info->strict_mode(), - info->is_generator()); + FastNewClosureStub stub(isolate(), info->strict_mode(), info->kind()); __ mov(ebx, Immediate(info)); __ CallStub(&stub); } else { @@ -1278,6 +1278,25 @@ void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { } +void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { + Comment cnmt(masm_, "[ SuperReference "); + + __ mov(LoadDescriptor::ReceiverRegister(), + Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); + + Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol()); + __ mov(LoadDescriptor::NameRegister(), home_object_symbol); + + CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); + + __ cmp(eax, isolate()->factory()->undefined_value()); + Label done; + __ j(not_equal, &done); + __ CallRuntime(Runtime::kThrowNonMethodError, 0); + __ bind(&done); +} + + void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, TypeofState typeof_state, Label* slow) { @@ -1328,10 +1347,10 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, // All extension objects were empty and it is safe to use a global // load IC call. - __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); - __ mov(LoadIC::NameRegister(), proxy->var()->name()); + __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadDescriptor::NameRegister(), proxy->var()->name()); if (FLAG_vector_ics) { - __ mov(LoadIC::SlotRegister(), + __ mov(VectorLoadICDescriptor::SlotRegister(), Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); } @@ -1415,10 +1434,10 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { switch (var->location()) { case Variable::UNALLOCATED: { Comment cmnt(masm_, "[ Global variable"); - __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); - __ mov(LoadIC::NameRegister(), var->name()); + __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadDescriptor::NameRegister(), var->name()); if (FLAG_vector_ics) { - __ mov(LoadIC::SlotRegister(), + __ mov(VectorLoadICDescriptor::SlotRegister(), Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); } CallLoadIC(CONTEXTUAL); @@ -1634,9 +1653,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { if (key->value()->IsInternalizedString()) { if (property->emit_store()) { VisitForAccumulatorValue(value); - DCHECK(StoreIC::ValueRegister().is(eax)); - __ mov(StoreIC::NameRegister(), Immediate(key->value())); - __ mov(StoreIC::ReceiverRegister(), Operand(esp, 0)); + DCHECK(StoreDescriptor::ValueRegister().is(eax)); + __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); + __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); CallStoreIC(key->LiteralFeedbackId()); PrepareForBailoutForId(key->id(), NO_REGISTERS); } else { @@ -1797,13 +1816,19 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { // Left-hand side can only be a property, a global or a (parameter or local) // slot. - enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; + enum LhsKind { + VARIABLE, + NAMED_PROPERTY, + KEYED_PROPERTY, + NAMED_SUPER_PROPERTY + }; LhsKind assign_type = VARIABLE; Property* property = expr->target()->AsProperty(); if (property != NULL) { assign_type = (property->key()->IsPropertyName()) - ? NAMED_PROPERTY - : KEYED_PROPERTY; + ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY + : NAMED_PROPERTY) + : KEYED_PROPERTY; } // Evaluate LHS expression. @@ -1811,11 +1836,20 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case VARIABLE: // Nothing to do here. break; + case NAMED_SUPER_PROPERTY: + VisitForStackValue(property->obj()->AsSuperReference()->this_var()); + EmitLoadHomeObject(property->obj()->AsSuperReference()); + __ push(result_register()); + if (expr->is_compound()) { + __ push(MemOperand(esp, kPointerSize)); + __ push(result_register()); + } + break; case NAMED_PROPERTY: if (expr->is_compound()) { // We need the receiver both on the stack and in the register. VisitForStackValue(property->obj()); - __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); + __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); } else { VisitForStackValue(property->obj()); } @@ -1824,8 +1858,8 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { if (expr->is_compound()) { VisitForStackValue(property->obj()); VisitForStackValue(property->key()); - __ mov(LoadIC::ReceiverRegister(), Operand(esp, kPointerSize)); - __ mov(LoadIC::NameRegister(), Operand(esp, 0)); + __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); + __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); } else { VisitForStackValue(property->obj()); VisitForStackValue(property->key()); @@ -1844,6 +1878,10 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { EmitVariableLoad(expr->target()->AsVariableProxy()); PrepareForBailout(expr->target(), TOS_REG); break; + case NAMED_SUPER_PROPERTY: + EmitNamedSuperPropertyLoad(property); + PrepareForBailoutForId(property->LoadId(), TOS_REG); + break; case NAMED_PROPERTY: EmitNamedPropertyLoad(property); PrepareForBailoutForId(property->LoadId(), TOS_REG); @@ -1893,6 +1931,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case NAMED_PROPERTY: EmitNamedPropertyAssignment(expr); break; + case NAMED_SUPER_PROPERTY: + EmitNamedSuperPropertyAssignment(expr); + break; case KEYED_PROPERTY: EmitKeyedPropertyAssignment(expr); break; @@ -1907,12 +1948,12 @@ void FullCodeGenerator::VisitYield(Yield* expr) { VisitForStackValue(expr->expression()); switch (expr->yield_kind()) { - case Yield::SUSPEND: + case Yield::kSuspend: // Pop value from top-of-stack slot; box result into result register. EmitCreateIteratorResult(false); __ push(result_register()); // Fall through. - case Yield::INITIAL: { + case Yield::kInitial: { Label suspend, continuation, post_runtime, resume; __ jmp(&suspend); @@ -1945,7 +1986,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { break; } - case Yield::FINAL: { + case Yield::kFinal: { VisitForAccumulatorValue(expr->generator_object()); __ mov(FieldOperand(result_register(), JSGeneratorObject::kContinuationOffset), @@ -1957,7 +1998,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { break; } - case Yield::DELEGATING: { + case Yield::kDelegating: { VisitForStackValue(expr->generator_object()); // Initial stack layout is as follows: @@ -1966,8 +2007,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) { Label l_catch, l_try, l_suspend, l_continuation, l_resume; Label l_next, l_call, l_loop; - Register load_receiver = LoadIC::ReceiverRegister(); - Register load_name = LoadIC::NameRegister(); + Register load_receiver = LoadDescriptor::ReceiverRegister(); + Register load_name = LoadDescriptor::NameRegister(); // Initial send value is undefined. __ mov(eax, isolate()->factory()->undefined_value()); @@ -2024,10 +2065,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ bind(&l_call); __ mov(load_receiver, Operand(esp, kPointerSize)); if (FLAG_vector_ics) { - __ mov(LoadIC::SlotRegister(), + __ mov(VectorLoadICDescriptor::SlotRegister(), Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); } - Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); + Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); CallIC(ic, TypeFeedbackId::None()); __ mov(edi, eax); __ mov(Operand(esp, 2 * kPointerSize), edi); @@ -2044,7 +2085,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ mov(load_name, isolate()->factory()->done_string()); // "done" if (FLAG_vector_ics) { - __ mov(LoadIC::SlotRegister(), + __ mov(VectorLoadICDescriptor::SlotRegister(), Immediate(Smi::FromInt(expr->DoneFeedbackSlot()))); } CallLoadIC(NOT_CONTEXTUAL); // result.done in eax @@ -2058,7 +2099,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ mov(load_name, isolate()->factory()->value_string()); // "value" if (FLAG_vector_ics) { - __ mov(LoadIC::SlotRegister(), + __ mov(VectorLoadICDescriptor::SlotRegister(), Immediate(Smi::FromInt(expr->ValueFeedbackSlot()))); } CallLoadIC(NOT_CONTEXTUAL); // result.value in eax @@ -2220,9 +2261,11 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Literal* key = prop->key()->AsLiteral(); DCHECK(!key->value()->IsSmi()); - __ mov(LoadIC::NameRegister(), Immediate(key->value())); + DCHECK(!prop->IsSuperAccess()); + + __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); if (FLAG_vector_ics) { - __ mov(LoadIC::SlotRegister(), + __ mov(VectorLoadICDescriptor::SlotRegister(), Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); CallLoadIC(NOT_CONTEXTUAL); } else { @@ -2231,11 +2274,23 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { } +void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { + // Stack: receiver, home_object. + SetSourcePosition(prop->position()); + Literal* key = prop->key()->AsLiteral(); + DCHECK(!key->value()->IsSmi()); + DCHECK(prop->IsSuperAccess()); + + __ push(Immediate(key->value())); + __ CallRuntime(Runtime::kLoadFromSuper, 3); +} + + void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); - Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); + Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); if (FLAG_vector_ics) { - __ mov(LoadIC::SlotRegister(), + __ mov(VectorLoadICDescriptor::SlotRegister(), Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); CallIC(ic); } else { @@ -2260,8 +2315,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, __ bind(&stub_call); __ mov(eax, ecx); - BinaryOpICStub stub(isolate(), op, mode); - CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); + Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); + CallIC(code, expr->BinaryOperationFeedbackId()); patch_site.EmitPatchInfo(); __ jmp(&done, Label::kNear); @@ -2343,9 +2398,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op, OverwriteMode mode) { __ pop(edx); - BinaryOpICStub stub(isolate(), op, mode); + Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. - CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); + CallIC(code, expr->BinaryOperationFeedbackId()); patch_site.EmitPatchInfo(); context()->Plug(eax); } @@ -2375,9 +2430,10 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { case NAMED_PROPERTY: { __ push(eax); // Preserve value. VisitForAccumulatorValue(prop->obj()); - __ Move(StoreIC::ReceiverRegister(), eax); - __ pop(StoreIC::ValueRegister()); // Restore value. - __ mov(StoreIC::NameRegister(), prop->key()->AsLiteral()->value()); + __ Move(StoreDescriptor::ReceiverRegister(), eax); + __ pop(StoreDescriptor::ValueRegister()); // Restore value. + __ mov(StoreDescriptor::NameRegister(), + prop->key()->AsLiteral()->value()); CallStoreIC(); break; } @@ -2385,12 +2441,11 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) { __ push(eax); // Preserve value. VisitForStackValue(prop->obj()); VisitForAccumulatorValue(prop->key()); - __ Move(KeyedStoreIC::NameRegister(), eax); - __ pop(KeyedStoreIC::ReceiverRegister()); // Receiver. - __ pop(KeyedStoreIC::ValueRegister()); // Restore value. - Handle<Code> ic = strict_mode() == SLOPPY - ? isolate()->builtins()->KeyedStoreIC_Initialize() - : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); + __ Move(StoreDescriptor::NameRegister(), eax); + __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. + __ pop(StoreDescriptor::ValueRegister()); // Restore value. + Handle<Code> ic = + CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); CallIC(ic); break; } @@ -2414,8 +2469,8 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { if (var->IsUnallocated()) { // Global var, const, or let. - __ mov(StoreIC::NameRegister(), var->name()); - __ mov(StoreIC::ReceiverRegister(), GlobalObjectOperand()); + __ mov(StoreDescriptor::NameRegister(), var->name()); + __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); CallStoreIC(); } else if (op == Token::INIT_CONST_LEGACY) { @@ -2488,28 +2543,44 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { // Record source code position before IC call. SetSourcePosition(expr->position()); - __ mov(StoreIC::NameRegister(), prop->key()->AsLiteral()->value()); - __ pop(StoreIC::ReceiverRegister()); + __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); + __ pop(StoreDescriptor::ReceiverRegister()); CallStoreIC(expr->AssignmentFeedbackId()); PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(eax); } +void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { + // Assignment to named property of super. + // eax : value + // stack : receiver ('this'), home_object + Property* prop = expr->target()->AsProperty(); + DCHECK(prop != NULL); + Literal* key = prop->key()->AsLiteral(); + DCHECK(key != NULL); + + __ push(eax); + __ push(Immediate(key->value())); + __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict + : Runtime::kStoreToSuper_Sloppy), + 4); + context()->Plug(eax); +} + + void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { // Assignment to a property, using a keyed store IC. // eax : value // esp[0] : key // esp[kPointerSize] : receiver - __ pop(KeyedStoreIC::NameRegister()); // Key. - __ pop(KeyedStoreIC::ReceiverRegister()); - DCHECK(KeyedStoreIC::ValueRegister().is(eax)); + __ pop(StoreDescriptor::NameRegister()); // Key. + __ pop(StoreDescriptor::ReceiverRegister()); + DCHECK(StoreDescriptor::ValueRegister().is(eax)); // Record source code position before IC call. SetSourcePosition(expr->position()); - Handle<Code> ic = strict_mode() == SLOPPY - ? isolate()->builtins()->KeyedStoreIC_Initialize() - : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); + Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); CallIC(ic, expr->AssignmentFeedbackId()); PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); @@ -2522,16 +2593,23 @@ void FullCodeGenerator::VisitProperty(Property* expr) { Expression* key = expr->key(); if (key->IsPropertyName()) { - VisitForAccumulatorValue(expr->obj()); - __ Move(LoadIC::ReceiverRegister(), result_register()); - EmitNamedPropertyLoad(expr); + if (!expr->IsSuperAccess()) { + VisitForAccumulatorValue(expr->obj()); + __ Move(LoadDescriptor::ReceiverRegister(), result_register()); + EmitNamedPropertyLoad(expr); + } else { + VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); + EmitLoadHomeObject(expr->obj()->AsSuperReference()); + __ push(result_register()); + EmitNamedSuperPropertyLoad(expr); + } PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(eax); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - __ pop(LoadIC::ReceiverRegister()); // Object. - __ Move(LoadIC::NameRegister(), result_register()); // Key. + __ pop(LoadDescriptor::ReceiverRegister()); // Object. + __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. EmitKeyedPropertyLoad(expr); context()->Plug(eax); } @@ -2549,11 +2627,10 @@ void FullCodeGenerator::CallIC(Handle<Code> code, void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { Expression* callee = expr->expression(); - CallIC::CallType call_type = callee->IsVariableProxy() - ? CallIC::FUNCTION - : CallIC::METHOD; + CallICState::CallType call_type = + callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD; // Get the target function. - if (call_type == CallIC::FUNCTION) { + if (call_type == CallICState::FUNCTION) { { StackValueContext context(this); EmitVariableLoad(callee->AsVariableProxy()); PrepareForBailout(callee, NO_REGISTERS); @@ -2564,7 +2641,8 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { } else { // Load the function from the receiver. DCHECK(callee->IsProperty()); - __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); + DCHECK(!callee->AsProperty()->IsSuperAccess()); + __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. @@ -2576,6 +2654,42 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { } +void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { + Expression* callee = expr->expression(); + DCHECK(callee->IsProperty()); + Property* prop = callee->AsProperty(); + DCHECK(prop->IsSuperAccess()); + + SetSourcePosition(prop->position()); + Literal* key = prop->key()->AsLiteral(); + DCHECK(!key->value()->IsSmi()); + // Load the function from the receiver. + SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); + EmitLoadHomeObject(super_ref); + __ push(eax); + VisitForAccumulatorValue(super_ref->this_var()); + __ push(eax); + __ push(eax); + __ push(Operand(esp, kPointerSize * 2)); + __ push(Immediate(key->value())); + // Stack here: + // - home_object + // - this (receiver) + // - this (receiver) <-- LoadFromSuper will pop here and below. + // - home_object + // - key + __ CallRuntime(Runtime::kLoadFromSuper, 3); + + // Replace home_object with target function. + __ mov(Operand(esp, kPointerSize), eax); + + // Stack here: + // - target function + // - this (receiver) + EmitCall(expr, CallICState::METHOD); +} + + // Code common for calls using the IC. void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { @@ -2586,8 +2700,8 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, // Load the function from the receiver. DCHECK(callee->IsProperty()); - __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); - __ mov(LoadIC::NameRegister(), eax); + __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); + __ mov(LoadDescriptor::NameRegister(), eax); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -2595,11 +2709,11 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, __ push(Operand(esp, 0)); __ mov(Operand(esp, kPointerSize), eax); - EmitCall(expr, CallIC::METHOD); + EmitCall(expr, CallICState::METHOD); } -void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) { +void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { // Load the arguments. ZoneList<Expression*>* args = expr->arguments(); int arg_count = args->length(); @@ -2736,15 +2850,21 @@ void FullCodeGenerator::VisitCall(Call* expr) { } else if (call_type == Call::PROPERTY_CALL) { Property* property = callee->AsProperty(); - { PreservePositionScope scope(masm()->positions_recorder()); - VisitForStackValue(property->obj()); - } - if (property->key()->IsPropertyName()) { - EmitCallWithLoadIC(expr); + bool is_named_call = property->key()->IsPropertyName(); + // super.x() is handled in EmitCallWithLoadIC. + if (property->IsSuperAccess() && is_named_call) { + EmitSuperCallWithLoadIC(expr); } else { - EmitKeyedCallWithLoadIC(expr, property->key()); + { + PreservePositionScope scope(masm()->positions_recorder()); + VisitForStackValue(property->obj()); + } + if (is_named_call) { + EmitCallWithLoadIC(expr); + } else { + EmitKeyedCallWithLoadIC(expr, property->key()); + } } - } else { DCHECK(call_type == Call::OTHER_CALL); // Call to an arbitrary expression not handled specially above. @@ -3247,7 +3367,7 @@ void FullCodeGenerator::EmitClassOf(CallRuntime* expr) { // Functions have class 'Function'. __ bind(&function); - __ mov(eax, isolate()->factory()->function_class_string()); + __ mov(eax, isolate()->factory()->Function_string()); __ jmp(&done); // Objects with a non-function constructor have class 'Object'. @@ -3365,9 +3485,9 @@ void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { Register index = ebx; Register value = ecx; - VisitForStackValue(args->at(1)); // index - VisitForStackValue(args->at(2)); // value - VisitForAccumulatorValue(args->at(0)); // string + VisitForStackValue(args->at(0)); // index + VisitForStackValue(args->at(1)); // value + VisitForAccumulatorValue(args->at(2)); // string __ pop(value); __ pop(index); @@ -3401,9 +3521,9 @@ void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { Register index = ebx; Register value = ecx; - VisitForStackValue(args->at(1)); // index - VisitForStackValue(args->at(2)); // value - VisitForAccumulatorValue(args->at(0)); // string + VisitForStackValue(args->at(0)); // index + VisitForStackValue(args->at(1)); // value + VisitForAccumulatorValue(args->at(2)); // string __ pop(value); __ pop(index); @@ -3754,7 +3874,7 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) { } -void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { +void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) { Label bailout, done, one_char_separator, long_separator, non_trivial_array, not_size_one_array, loop, loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry; @@ -3812,7 +3932,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { array = no_reg; - // Check that all array elements are sequential ASCII strings, and + // Check that all array elements are sequential one-byte strings, and // accumulate the sum of their lengths, as a smi-encoded value. __ Move(index, Immediate(0)); __ Move(string_length, Immediate(0)); @@ -3821,7 +3941,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { // scratch, string_length, elements. if (generate_debug_code_) { __ cmp(index, array_length); - __ Assert(less, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); + __ Assert(less, kNoEmptyArraysHereInEmitFastOneByteArrayJoin); } __ bind(&loop); __ mov(string, FieldOperand(elements, @@ -3859,7 +3979,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { // string_length: Sum of string lengths, as a smi. // elements: FixedArray of strings. - // Check that the separator is a flat ASCII string. + // Check that the separator is a flat one-byte string. __ mov(string, separator_operand); __ JumpIfSmi(string, &bailout); __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); @@ -3883,8 +4003,8 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { // Live registers and stack values: // string_length // elements - __ AllocateAsciiString(result_pos, string_length, scratch, - index, string, &bailout); + __ AllocateOneByteString(result_pos, string_length, scratch, index, string, + &bailout); __ mov(result_operand, result_pos); __ lea(result_pos, FieldOperand(result_pos, SeqOneByteString::kHeaderSize)); @@ -3927,7 +4047,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { // One-character separator case __ bind(&one_char_separator); - // Replace separator with its ASCII character value. + // Replace separator with its one-byte character value. __ mov_b(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); __ mov_b(separator_operand, scratch); @@ -4045,10 +4165,10 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); // Load the function from the receiver. - __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); - __ mov(LoadIC::NameRegister(), Immediate(expr->name())); + __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); + __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name())); if (FLAG_vector_ics) { - __ mov(LoadIC::SlotRegister(), + __ mov(VectorLoadICDescriptor::SlotRegister(), Immediate(Smi::FromInt(expr->CallRuntimeFeedbackSlot()))); CallLoadIC(NOT_CONTEXTUAL); } else { @@ -4220,6 +4340,11 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { if (prop != NULL) { assign_type = (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; + if (prop->IsSuperAccess()) { + // throw exception. + VisitSuperReference(prop->obj()->AsSuperReference()); + return; + } } // Evaluate expression and get value. @@ -4235,14 +4360,14 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { if (assign_type == NAMED_PROPERTY) { // Put the object both on the stack and in the register. VisitForStackValue(prop->obj()); - __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); + __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); EmitNamedPropertyLoad(prop); } else { VisitForStackValue(prop->obj()); VisitForStackValue(prop->key()); - __ mov(LoadIC::ReceiverRegister(), - Operand(esp, kPointerSize)); // Object. - __ mov(LoadIC::NameRegister(), Operand(esp, 0)); // Key. + __ mov(LoadDescriptor::ReceiverRegister(), + Operand(esp, kPointerSize)); // Object. + __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. EmitKeyedPropertyLoad(prop); } } @@ -4327,8 +4452,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { __ bind(&stub_call); __ mov(edx, eax); __ mov(eax, Immediate(Smi::FromInt(1))); - BinaryOpICStub stub(isolate(), expr->binary_op(), NO_OVERWRITE); - CallIC(stub.GetCode(), expr->CountBinOpFeedbackId()); + Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), + NO_OVERWRITE).code(); + CallIC(code, expr->CountBinOpFeedbackId()); patch_site.EmitPatchInfo(); __ bind(&done); @@ -4357,8 +4483,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { } break; case NAMED_PROPERTY: { - __ mov(StoreIC::NameRegister(), prop->key()->AsLiteral()->value()); - __ pop(StoreIC::ReceiverRegister()); + __ mov(StoreDescriptor::NameRegister(), + prop->key()->AsLiteral()->value()); + __ pop(StoreDescriptor::ReceiverRegister()); CallStoreIC(expr->CountStoreFeedbackId()); PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { @@ -4371,11 +4498,10 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { break; } case KEYED_PROPERTY: { - __ pop(KeyedStoreIC::NameRegister()); - __ pop(KeyedStoreIC::ReceiverRegister()); - Handle<Code> ic = strict_mode() == SLOPPY - ? isolate()->builtins()->KeyedStoreIC_Initialize() - : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); + __ pop(StoreDescriptor::NameRegister()); + __ pop(StoreDescriptor::ReceiverRegister()); + Handle<Code> ic = + CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); CallIC(ic, expr->CountStoreFeedbackId()); PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { @@ -4399,10 +4525,10 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { if (proxy != NULL && proxy->var()->IsUnallocated()) { Comment cmnt(masm_, "[ Global variable"); - __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); - __ mov(LoadIC::NameRegister(), Immediate(proxy->name())); + __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name())); if (FLAG_vector_ics) { - __ mov(LoadIC::SlotRegister(), + __ mov(VectorLoadICDescriptor::SlotRegister(), Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); } // Use a regular load, not a contextual load, to avoid a reference @@ -4564,7 +4690,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { // Record position and call the compare IC. SetSourcePosition(expr->position()); - Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); + Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); CallIC(ic, expr->CompareOperationFeedbackId()); patch_site.EmitPatchInfo(); |