23 #define __ ACCESS_MASM(masm_)
28 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
30 info_emitted_ =
false;
35 DCHECK(patch_site_.is_bound() == info_emitted_);
38 void EmitJumpIfNotSmi(Register reg,
40 Label::Distance distance = Label::kFar) {
45 void EmitJumpIfSmi(Register reg,
47 Label::Distance distance = Label::kFar) {
49 EmitJump(
carry, target, distance);
52 void EmitPatchInfo() {
53 if (patch_site_.is_bound()) {
54 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_);
55 DCHECK(is_uint8(delta_to_patch_site));
56 __ test(
eax, Immediate(delta_to_patch_site));
67 void EmitJump(
Condition cc, Label* target, Label::Distance distance) {
68 DCHECK(!patch_site_.is_bound() && !info_emitted_);
70 __ bind(&patch_site_);
71 __ j(
cc, target, distance);
74 MacroAssembler* masm_;
96 CompilationInfo* info =
info_;
98 isolate()->factory()->NewFixedArray(
function()->handler_count(),
TENURED);
101 Handle<Smi>(
Smi::FromInt(FLAG_interrupt_budget), isolate()));
103 Comment cmnt(
masm_,
"[ function compiled by full code generator");
108 if (strlen(FLAG_stop_at) > 0 &&
109 info->function()->name()->IsUtf8EqualTo(
CStrVector(FLAG_stop_at))) {
117 if (info->strict_mode() ==
SLOPPY && !info->is_native()) {
120 int receiver_offset = (info->scope()->num_parameters() + 1) *
kPointerSize;
121 __ mov(
ecx, Operand(
esp, receiver_offset));
123 __ cmp(
ecx, isolate()->factory()->undefined_value());
129 __ mov(Operand(
esp, receiver_offset),
ecx);
137 FrameScope frame_scope(
masm_, StackFrame::MANUAL);
140 __ Prologue(info->IsCodePreAgingActive());
143 { Comment cmnt(
masm_,
"[ Allocate locals");
144 int locals_count = info->scope()->num_stack_slots();
146 DCHECK(!info->function()->is_generator() || locals_count == 0);
147 if (locals_count == 1) {
148 __ push(Immediate(isolate()->factory()->undefined_value()));
149 }
else if (locals_count > 1) {
150 if (locals_count >= 128) {
154 ExternalReference stack_limit =
155 ExternalReference::address_of_real_stack_limit(isolate());
156 __ cmp(
ecx, Operand::StaticVariable(stack_limit));
161 __ mov(
eax, Immediate(isolate()->factory()->undefined_value()));
162 const int kMaxPushes = 32;
163 if (locals_count >= kMaxPushes) {
164 int loop_iterations = locals_count / kMaxPushes;
165 __ mov(
ecx, loop_iterations);
167 __ bind(&loop_header);
169 for (
int i = 0;
i < kMaxPushes;
i++) {
175 int remaining = locals_count % kMaxPushes;
177 for (
int i = 0;
i < remaining;
i++) {
183 bool function_in_register =
true;
187 if (heap_slots > 0) {
188 Comment cmnt(
masm_,
"[ Allocate context");
189 bool need_write_barrier =
true;
191 if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
193 __ Push(info->scope()->GetScopeInfo());
194 __ CallRuntime(Runtime::kNewGlobalContext, 2);
195 }
else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
196 FastNewContextStub stub(isolate(), heap_slots);
199 need_write_barrier =
false;
202 __ CallRuntime(Runtime::kNewFunctionContext, 1);
204 function_in_register =
false;
211 int num_parameters = info->scope()->num_parameters();
212 for (
int i = 0;
i < num_parameters;
i++) {
214 if (var->IsContextSlot()) {
218 __ mov(
eax, Operand(
ebp, parameter_offset));
221 __ mov(Operand(
esi, context_offset),
eax);
223 if (need_write_barrier) {
224 __ RecordWriteContextSlot(
esi, context_offset,
eax,
ebx,
226 }
else if (FLAG_debug_code) {
228 __ JumpIfInNewSpace(
esi,
eax, &done, Label::kNear);
229 __ Abort(kExpectedNewSpaceObject);
237 if (arguments !=
NULL) {
239 Comment cmnt(
masm_,
"[ Allocate arguments object");
240 if (function_in_register) {
246 int num_parameters = info->scope()->num_parameters();
264 ArgumentsAccessStub stub(isolate(), type);
271 __ CallRuntime(Runtime::kTraceEnter, 0);
276 if (
scope()->HasIllegalRedeclaration()) {
277 Comment cmnt(
masm_,
"[ Declarations");
282 { Comment cmnt(
masm_,
"[ Declarations");
285 if (
scope()->is_function_scope() &&
scope()->
function() !=
NULL) {
290 VisitVariableDeclaration(
function);
295 { Comment cmnt(
masm_,
"[ Stack check");
298 ExternalReference stack_limit
299 = ExternalReference::address_of_stack_limit(isolate());
300 __ cmp(
esp, Operand::StaticVariable(stack_limit));
306 { Comment cmnt(
masm_,
"[ Body");
308 VisitStatements(
function()->body());
315 { Comment cmnt(
masm_,
"[ return <undefined>;");
316 __ mov(
eax, isolate()->factory()->undefined_value());
335 int reset_value = FLAG_interrupt_budget;
343 Label* back_edge_target) {
344 Comment cmnt(
masm_,
"[ Back edge bookkeeping");
347 DCHECK(back_edge_target->is_bound());
350 Max(1, distance / kCodeSizeMultiplier));
372 Comment cmnt(
masm_,
"[ Return sequence");
380 __ CallRuntime(Runtime::kTraceExit, 1);
385 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
389 Max(1, distance / kCodeSizeMultiplier));
395 __ call(isolate()->builtins()->InterruptCheck(),
402 Label check_exit_codesize;
414 __ Ret(arguments_bytes,
ecx);
425 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
430 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
436 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
446 codegen()->PrepareForBailoutBeforeSplit(condition(),
false,
NULL,
NULL);
447 codegen()->DoTest(
this);
478 Handle<Object> lit)
const {
489 __ SafePush(Immediate(lit));
491 __ push(Immediate(lit));
497 codegen()->PrepareForBailoutBeforeSplit(condition(),
501 DCHECK(!lit->IsUndetectableObject());
502 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
503 if (false_label_ != fall_through_)
__ jmp(false_label_);
504 }
else if (lit->IsTrue() || lit->IsJSObject()) {
505 if (true_label_ != fall_through_)
__ jmp(true_label_);
506 }
else if (lit->IsString()) {
507 if (String::cast(*lit)->length() == 0) {
508 if (false_label_ != fall_through_)
__ jmp(false_label_);
510 if (true_label_ != fall_through_)
__ jmp(true_label_);
512 }
else if (lit->IsSmi()) {
513 if (Smi::cast(*lit)->value() == 0) {
514 if (false_label_ != fall_through_)
__ jmp(false_label_);
516 if (true_label_ != fall_through_)
__ jmp(true_label_);
521 codegen()->DoTest(
this);
527 Register reg)
const {
535 Register reg)
const {
543 Register reg)
const {
545 if (count > 1)
__ Drop(count - 1);
546 __ mov(Operand(
esp, 0), reg);
551 Register reg)
const {
556 codegen()->PrepareForBailoutBeforeSplit(condition(),
false,
NULL,
NULL);
557 codegen()->DoTest(
this);
562 Label* materialize_false)
const {
563 DCHECK(materialize_true == materialize_false);
564 __ bind(materialize_true);
569 Label* materialize_true,
570 Label* materialize_false)
const {
572 __ bind(materialize_true);
574 __ jmp(&done, Label::kNear);
575 __ bind(materialize_false);
582 Label* materialize_true,
583 Label* materialize_false)
const {
585 __ bind(materialize_true);
586 __ push(Immediate(isolate()->factory()->true_value()));
587 __ jmp(&done, Label::kNear);
588 __ bind(materialize_false);
589 __ push(Immediate(isolate()->factory()->false_value()));
595 Label* materialize_false)
const {
596 DCHECK(materialize_true == true_label_);
597 DCHECK(materialize_false == false_label_);
606 Handle<Object> value =
flag
607 ? isolate()->factory()->true_value()
608 : isolate()->factory()->false_value();
614 Handle<Object> value =
flag
615 ? isolate()->factory()->true_value()
616 : isolate()->factory()->false_value();
617 __ push(Immediate(value));
622 codegen()->PrepareForBailoutBeforeSplit(condition(),
627 if (true_label_ != fall_through_)
__ jmp(true_label_);
629 if (false_label_ != fall_through_)
__ jmp(false_label_);
637 Label* fall_through) {
639 CallIC(ic, condition->test_id());
649 Label* fall_through) {
650 if (if_false == fall_through) {
652 }
else if (if_true == fall_through) {
662 DCHECK(var->IsStackAllocated());
666 if (var->IsParameter()) {
671 return Operand(
ebp, offset);
676 DCHECK(var->IsContextSlot() || var->IsStackAllocated());
677 if (var->IsContextSlot()) {
679 __ LoadContext(scratch, context_chain_length);
688 DCHECK(var->IsContextSlot() || var->IsStackAllocated());
690 __ mov(dest, location);
698 DCHECK(var->IsContextSlot() || var->IsStackAllocated());
699 DCHECK(!scratch0.is(src));
700 DCHECK(!scratch0.is(scratch1));
701 DCHECK(!scratch1.is(src));
703 __ mov(location, src);
706 if (var->IsContextSlot()) {
715 bool should_normalize,
724 if (should_normalize)
__ jmp(&skip, Label::kNear);
726 if (should_normalize) {
727 __ cmp(
eax, isolate()->factory()->true_value());
740 __ cmp(
ebx, isolate()->factory()->with_context_map());
742 __ cmp(
ebx, isolate()->factory()->catch_context_map());
748 void FullCodeGenerator::VisitVariableDeclaration(
749 VariableDeclaration* declaration) {
753 VariableProxy* proxy = declaration->proxy();
755 Variable* variable = proxy->var();
757 switch (variable->location()) {
759 globals_->Add(variable->name(), zone());
760 globals_->Add(variable->binding_needs_init()
761 ? isolate()->factory()->the_hole_value()
762 : isolate()->factory()->undefined_value(), zone());
768 Comment cmnt(
masm_,
"[ VariableDeclaration");
770 Immediate(isolate()->factory()->the_hole_value()));
776 Comment cmnt(
masm_,
"[ VariableDeclaration");
779 Immediate(isolate()->factory()->the_hole_value()));
786 Comment cmnt(
masm_,
"[ VariableDeclaration");
788 __ push(Immediate(variable->name()));
799 __ push(Immediate(isolate()->factory()->the_hole_value()));
803 __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
810 void FullCodeGenerator::VisitFunctionDeclaration(
811 FunctionDeclaration* declaration) {
812 VariableProxy* proxy = declaration->proxy();
813 Variable* variable = proxy->var();
814 switch (variable->location()) {
816 globals_->Add(variable->name(), zone());
817 Handle<SharedFunctionInfo>
function =
820 if (
function.is_null())
return SetStackOverflow();
827 Comment cmnt(
masm_,
"[ FunctionDeclaration");
834 Comment cmnt(
masm_,
"[ FunctionDeclaration");
847 Comment cmnt(
masm_,
"[ FunctionDeclaration");
849 __ push(Immediate(variable->name()));
852 __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
859 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
860 Variable* variable = declaration->proxy()->var();
862 DCHECK(variable->interface()->IsFrozen());
864 Comment cmnt(
masm_,
"[ ModuleDeclaration");
881 Visit(declaration->module());
885 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
886 VariableProxy* proxy = declaration->proxy();
887 Variable* variable = proxy->var();
888 switch (variable->location()) {
894 Comment cmnt(
masm_,
"[ ImportDeclaration");
908 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) {
918 __ CallRuntime(Runtime::kDeclareGlobals, 3);
926 __ CallRuntime(Runtime::kDeclareModules, 1);
931 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
932 Comment cmnt(
masm_,
"[ SwitchStatement");
933 Breakable nested_statement(
this, stmt);
940 ZoneList<CaseClause*>* clauses = stmt->cases();
941 CaseClause* default_clause =
NULL;
945 for (
int i = 0;
i < clauses->length();
i++) {
946 CaseClause* clause = clauses->at(
i);
947 clause->body_target()->Unuse();
950 if (clause->is_default()) {
951 default_clause = clause;
955 Comment cmnt(
masm_,
"[ Case comparison");
965 JumpPatchSite patch_site(
masm_);
966 if (inline_smi_code) {
970 patch_site.EmitJumpIfNotSmi(
ecx, &slow_case, Label::kNear);
975 __ jmp(clause->body_target());
982 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
983 CallIC(ic, clause->CompareId());
984 patch_site.EmitPatchInfo();
987 __ jmp(&skip, Label::kNear);
989 __ cmp(
eax, isolate()->factory()->true_value());
992 __ jmp(clause->body_target());
998 __ jmp(clause->body_target());
1003 __ bind(&next_test);
1005 if (default_clause ==
NULL) {
1006 __ jmp(nested_statement.break_label());
1008 __ jmp(default_clause->body_target());
1012 for (
int i = 0;
i < clauses->length();
i++) {
1013 Comment cmnt(
masm_,
"[ Case body");
1014 CaseClause* clause = clauses->at(
i);
1015 __ bind(clause->body_target());
1017 VisitStatements(clause->statements());
1020 __ bind(nested_statement.break_label());
1025 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1026 Comment cmnt(
masm_,
"[ ForInStatement");
1027 int slot = stmt->ForInFeedbackSlot();
1032 ForIn loop_statement(
this, stmt);
1038 __ cmp(
eax, isolate()->factory()->undefined_value());
1040 __ cmp(
eax, isolate()->factory()->null_value());
1046 Label convert, done_convert;
1047 __ JumpIfSmi(
eax, &convert, Label::kNear);
1053 __ bind(&done_convert);
1057 Label call_runtime, use_cache, fixed_array;
1066 __ CheckEnumCache(&call_runtime);
1069 __ jmp(&use_cache, Label::kNear);
1072 __ bind(&call_runtime);
1074 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
1076 isolate()->factory()->meta_map());
1081 Label no_descriptors;
1082 __ bind(&use_cache);
1088 __ LoadInstanceDescriptors(
eax,
ecx);
1099 __ bind(&no_descriptors);
1105 __ bind(&fixed_array);
1118 __ bind(&non_proxy);
1145 __ j(
equal, &update_each, Label::kNear);
1151 __ j(
zero, &update_each);
1160 __ j(
equal, loop_statement.continue_label());
1165 __ bind(&update_each);
1168 { EffectContext
context(
this);
1173 Visit(stmt->body());
1177 __ bind(loop_statement.continue_label());
1184 __ bind(loop_statement.break_label());
1194 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
1195 Comment cmnt(
masm_,
"[ ForOfStatement");
1198 Iteration loop_statement(
this, stmt);
1205 __ bind(loop_statement.continue_label());
1211 Label result_not_done;
1213 loop_statement.break_label(),
1216 __ bind(&result_not_done);
1222 Visit(stmt->body());
1227 __ jmp(loop_statement.continue_label());
1231 __ bind(loop_statement.break_label());
1244 if (!FLAG_always_opt &&
1245 !FLAG_prepare_always_opt &&
1247 scope()->is_function_scope() &&
1248 info->num_literals() == 0) {
1249 FastNewClosureStub stub(isolate(), info->strict_mode(), info->kind());
1250 __ mov(
ebx, Immediate(info));
1254 __ push(Immediate(info));
1255 __ push(Immediate(pretenure
1256 ? isolate()->factory()->true_value()
1257 : isolate()->factory()->false_value()));
1258 __ CallRuntime(Runtime::kNewClosure, 3);
1264 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
1265 Comment cmnt(
masm_,
"[ VariableProxy");
1271 Comment cnmt(
masm_,
"[ SuperReference ");
1276 Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
1281 __ cmp(
eax, isolate()->factory()->undefined_value());
1284 __ CallRuntime(Runtime::kThrowNonMethodError, 0);
1293 Register temp =
edx;
1297 if (s->num_heap_slots() > 0) {
1298 if (s->calls_sloppy_eval()) {
1312 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope())
break;
1313 s = s->outer_scope();
1316 if (s !=
NULL && s->is_eval_scope()) {
1326 Immediate(isolate()->factory()->native_context_map()));
1327 __ j(
equal, &fast, Label::kNear);
1341 if (FLAG_vector_ics) {
1343 Immediate(
Smi::FromInt(proxy->VariableFeedbackSlot())));
1356 DCHECK(var->IsContextSlot());
1358 Register temp =
ebx;
1361 if (s->num_heap_slots() > 0) {
1362 if (s->calls_sloppy_eval()) {
1393 Variable* var = proxy->var();
1398 Variable* local = var->local_if_not_shadowed();
1400 if (local->mode() ==
LET || local->mode() ==
CONST ||
1402 __ cmp(
eax, isolate()->factory()->the_hole_value());
1405 __ mov(
eax, isolate()->factory()->undefined_value());
1407 __ push(Immediate(var->name()));
1408 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1419 Variable* var = proxy->var();
1423 switch (var->location()) {
1425 Comment cmnt(
masm_,
"[ Global variable");
1428 if (FLAG_vector_ics) {
1430 Immediate(
Smi::FromInt(proxy->VariableFeedbackSlot())));
1440 Comment cmnt(
masm_, var->IsContextSlot() ?
"[ Context variable"
1441 :
"[ Stack variable");
1442 if (var->binding_needs_init()) {
1466 bool skip_init_check;
1467 if (var->scope()->DeclarationScope() !=
scope()->DeclarationScope()) {
1468 skip_init_check =
false;
1474 var->initializer_position() < proxy->position();
1477 if (!skip_init_check) {
1481 __ cmp(
eax, isolate()->factory()->the_hole_value());
1483 if (var->mode() ==
LET || var->mode() ==
CONST) {
1486 __ push(Immediate(var->name()));
1487 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1491 __ mov(
eax, isolate()->factory()->undefined_value());
1503 Comment cmnt(
masm_,
"[ Lookup variable");
1510 __ push(Immediate(var->name()));
1511 __ CallRuntime(Runtime::kLoadLookupSlot, 2);
1520 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1521 Comment cmnt(
masm_,
"[ RegExpLiteral");
1530 int literal_offset =
1533 __ cmp(
ebx, isolate()->factory()->undefined_value());
1540 __ push(Immediate(expr->pattern()));
1541 __ push(Immediate(expr->flags()));
1542 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1545 __ bind(&materialized);
1547 Label allocated, runtime_allocate;
1551 __ bind(&runtime_allocate);
1554 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1557 __ bind(&allocated);
1575 if (expression ==
NULL) {
1576 __ push(Immediate(isolate()->factory()->null_value()));
1583 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1584 Comment cmnt(
masm_,
"[ ObjectLiteral");
1586 expr->BuildConstantProperties(isolate());
1587 Handle<FixedArray> constant_properties = expr->constant_properties();
1588 int flags = expr->fast_elements()
1589 ? ObjectLiteral::kFastElements
1590 : ObjectLiteral::kNoFlags;
1591 flags |= expr->has_function()
1592 ? ObjectLiteral::kHasFunction
1593 : ObjectLiteral::kNoFlags;
1594 int properties_count = constant_properties->length() / 2;
1595 if (expr->may_store_doubles() || expr->depth() > 1 ||
1596 masm()->serializer_enabled() ||
1597 flags != ObjectLiteral::kFastElements ||
1602 __ push(Immediate(constant_properties));
1604 __ CallRuntime(Runtime::kCreateObjectLiteral, 4);
1609 __ mov(
ecx, Immediate(constant_properties));
1611 FastCloneShallowObjectStub stub(isolate(), properties_count);
1617 bool result_saved =
false;
1622 expr->CalculateEmitStore(zone());
1624 AccessorTable accessor_table(zone());
1625 for (
int i = 0;
i < expr->properties()->length();
i++) {
1626 ObjectLiteral::Property*
property = expr->properties()->at(
i);
1627 if (property->IsCompileTimeValue())
continue;
1629 Literal* key =
property->key();
1630 Expression* value =
property->value();
1631 if (!result_saved) {
1633 result_saved =
true;
1635 switch (property->kind()) {
1638 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1641 case ObjectLiteral::Property::COMPUTED:
1642 if (key->value()->IsInternalizedString()) {
1643 if (property->emit_store()) {
1655 __ push(Operand(
esp, 0));
1658 if (property->emit_store()) {
1660 __ CallRuntime(Runtime::kSetProperty, 4);
1665 case ObjectLiteral::Property::PROTOTYPE:
1666 __ push(Operand(
esp, 0));
1668 if (property->emit_store()) {
1669 __ CallRuntime(Runtime::kSetPrototype, 2);
1674 case ObjectLiteral::Property::GETTER:
1675 accessor_table.lookup(key)->second->getter = value;
1677 case ObjectLiteral::Property::SETTER:
1678 accessor_table.lookup(key)->second->setter = value;
1685 for (AccessorTable::Iterator it = accessor_table.begin();
1686 it != accessor_table.end();
1688 __ push(Operand(
esp, 0));
1693 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1696 if (expr->has_function()) {
1698 __ push(Operand(
esp, 0));
1699 __ CallRuntime(Runtime::kToFastProperties, 1);
1710 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1711 Comment cmnt(
masm_,
"[ ArrayLiteral");
1713 expr->BuildConstantElements(isolate());
1714 int flags = expr->depth() == 1
1715 ? ArrayLiteral::kShallowElements
1716 : ArrayLiteral::kNoFlags;
1718 ZoneList<Expression*>* subexprs = expr->values();
1719 int length = subexprs->length();
1720 Handle<FixedArray> constant_elements = expr->constant_elements();
1721 DCHECK_EQ(2, constant_elements->length());
1723 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value());
1724 bool has_constant_fast_elements =
1726 Handle<FixedArrayBase> constant_elements_values(
1727 FixedArrayBase::cast(constant_elements->get(1)));
1730 if (has_constant_fast_elements && !FLAG_allocation_site_pretenuring) {
1740 __ push(Immediate(constant_elements));
1742 __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
1747 __ mov(
ecx, Immediate(constant_elements));
1748 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1752 bool result_saved =
false;
1756 for (
int i = 0;
i < length;
i++) {
1757 Expression* subexpr = subexprs->at(
i);
1762 if (!result_saved) {
1765 result_saved =
true;
1783 StoreArrayLiteralElementStub stub(isolate());
1799 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1800 DCHECK(expr->target()->IsValidReferenceExpression());
1802 Comment cmnt(
masm_,
"[ Assignment");
1810 NAMED_SUPER_PROPERTY
1813 Property*
property = expr->target()->AsProperty();
1814 if (property !=
NULL) {
1815 assign_type = (
property->key()->IsPropertyName())
1816 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
1822 switch (assign_type) {
1826 case NAMED_SUPER_PROPERTY:
1830 if (expr->is_compound()) {
1836 if (expr->is_compound()) {
1845 if (expr->is_compound()) {
1860 if (expr->is_compound()) {
1861 AccumulatorValueContext result_context(
this);
1862 { AccumulatorValueContext left_operand_context(
this);
1863 switch (assign_type) {
1868 case NAMED_SUPER_PROPERTY:
1911 switch (assign_type) {
1921 case NAMED_SUPER_PROPERTY:
1931 void FullCodeGenerator::VisitYield(Yield* expr) {
1932 Comment cmnt(
masm_,
"[ Yield");
1937 switch (expr->yield_kind()) {
1938 case Yield::kSuspend:
1943 case Yield::kInitial: {
1944 Label suspend, continuation, post_runtime, resume;
1948 __ bind(&continuation);
1964 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1967 __ bind(&post_runtime);
1976 case Yield::kFinal: {
1988 case Yield::kDelegating: {
1995 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
1996 Label l_next, l_call, l_loop;
2001 __ mov(
eax, isolate()->factory()->undefined_value());
2007 __ mov(load_name, isolate()->factory()->throw_string());
2018 __ PushTryHandler(StackHandler::CATCH, expr->index());
2022 __ bind(&l_continuation);
2024 __ bind(&l_suspend);
2025 const int generator_object_depth =
kPointerSize + handler_size;
2026 __ mov(
eax, Operand(
esp, generator_object_depth));
2035 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2046 __ mov(load_name, isolate()->factory()->next_string());
2054 if (FLAG_vector_ics) {
2056 Immediate(
Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
2058 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2071 __ Move(load_receiver,
eax);
2073 isolate()->factory()->done_string());
2074 if (FLAG_vector_ics) {
2085 __ pop(load_receiver);
2087 isolate()->factory()->value_string());
2088 if (FLAG_vector_ics) {
2112 Label wrong_state, closed_state, done;
2118 __ j(
less, &wrong_state);
2131 __ mov(
ecx, isolate()->factory()->the_hole_value());
2132 Label push_argument_holes, push_frame;
2133 __ bind(&push_argument_holes);
2137 __ jmp(&push_argument_holes);
2142 __ bind(&push_frame);
2143 __ call(&resume_frame);
2145 __ bind(&resume_frame);
2160 __ cmp(
edx, Immediate(0));
2169 __ bind(&slow_resume);
2174 Label push_operand_holes, call_resume;
2175 __ bind(&push_operand_holes);
2176 __ sub(
edx, Immediate(1));
2179 __ jmp(&push_operand_holes);
2180 __ bind(&call_resume);
2184 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2186 __ Abort(kGeneratorFailedToResume);
2189 __ bind(&closed_state);
2192 __ push(Immediate(isolate()->factory()->undefined_value()));
2198 __ CallRuntime(Runtime::kThrow, 1);
2203 __ bind(&wrong_state);
2205 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2216 Handle<Map>
map(isolate()->native_context()->iterator_result_map());
2221 __ bind(&gc_required);
2223 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
2227 __ bind(&allocated);
2230 __ mov(
edx, isolate()->factory()->ToBoolean(done));
2234 isolate()->factory()->empty_fixed_array());
2236 isolate()->factory()->empty_fixed_array());
2249 Literal* key = prop->key()->AsLiteral();
2250 DCHECK(!key->value()->IsSmi());
2251 DCHECK(!prop->IsSuperAccess());
2254 if (FLAG_vector_ics) {
2256 Immediate(
Smi::FromInt(prop->PropertyFeedbackSlot())));
2267 Literal* key = prop->key()->AsLiteral();
2268 DCHECK(!key->value()->IsSmi());
2269 DCHECK(prop->IsSuperAccess());
2271 __ push(Immediate(key->value()));
2272 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2278 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2279 if (FLAG_vector_ics) {
2281 Immediate(
Smi::FromInt(prop->PropertyFeedbackSlot())));
2284 CallIC(ic, prop->PropertyFeedbackId());
2293 Expression* right) {
2296 Label smi_case, done, stub_call;
2300 JumpPatchSite patch_site(
masm_);
2301 patch_site.EmitJumpIfSmi(
eax, &smi_case, Label::kNear);
2303 __ bind(&stub_call);
2305 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op,
mode).code();
2306 CallIC(code, expr->BinaryOperationFeedbackId());
2307 patch_site.EmitPatchInfo();
2308 __ jmp(&done, Label::kNear);
2326 __ cmp(
eax, 0xc0000000);
2330 __ bind(&result_ok);
2339 __ test(
eax, Immediate(0xc0000000));
2343 __ bind(&result_ok);
2369 case Token::BIT_AND:
2372 case Token::BIT_XOR:
2388 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op,
mode).code();
2389 JumpPatchSite patch_site(
masm_);
2390 CallIC(code, expr->BinaryOperationFeedbackId());
2391 patch_site.EmitPatchInfo();
2397 DCHECK(expr->IsValidReferenceExpression());
2403 Property* prop = expr->AsProperty();
2405 assign_type = (prop->key()->IsPropertyName())
2410 switch (assign_type) {
2412 Variable* var = expr->AsVariableProxy()->var();
2423 prop->key()->AsLiteral()->value());
2435 CodeFactory::KeyedStoreIC(isolate(),
strict_mode()).code();
2446 __ mov(location,
eax);
2447 if (var->IsContextSlot()) {
2457 if (var->IsUnallocated()) {
2463 }
else if (op == Token::INIT_CONST_LEGACY) {
2465 DCHECK(!var->IsParameter());
2466 if (var->IsLookupSlot()) {
2469 __ push(Immediate(var->name()));
2470 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
2472 DCHECK(var->IsStackLocal() || var->IsContextSlot());
2475 __ mov(
edx, location);
2476 __ cmp(
edx, isolate()->factory()->the_hole_value());
2482 }
else if (var->mode() ==
LET && op != Token::INIT_LET) {
2484 DCHECK(!var->IsLookupSlot());
2485 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2488 __ mov(
edx, location);
2489 __ cmp(
edx, isolate()->factory()->the_hole_value());
2491 __ push(Immediate(var->name()));
2492 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2496 }
else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2497 if (var->IsLookupSlot()) {
2501 __ push(Immediate(var->name()));
2503 __ CallRuntime(Runtime::kStoreLookupSlot, 4);
2507 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2511 __ mov(
edx, location);
2512 __ cmp(
edx, isolate()->factory()->the_hole_value());
2513 __ Check(
equal, kLetBindingReInitialization);
2527 Property* prop = expr->target()->AsProperty();
2529 DCHECK(prop->key()->IsLiteral());
2545 Property* prop = expr->target()->AsProperty();
2547 Literal* key = prop->key()->AsLiteral();
2551 __ push(Immediate(key->value()));
2553 : Runtime::kStoreToSuper_Sloppy),
2570 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(),
strict_mode()).code();
2571 CallIC(ic, expr->AssignmentFeedbackId());
2578 void FullCodeGenerator::VisitProperty(Property* expr) {
2579 Comment cmnt(
masm_,
"[ Property");
2580 Expression* key = expr->key();
2582 if (key->IsPropertyName()) {
2583 if (!expr->IsSuperAccess()) {
2607 TypeFeedbackId ast_id) {
2615 Expression* callee = expr->expression();
2617 CallICState::CallType call_type =
2618 callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
2620 if (call_type == CallICState::FUNCTION) {
2621 { StackValueContext
context(
this);
2627 __ push(Immediate(isolate()->factory()->undefined_value()));
2630 DCHECK(callee->IsProperty());
2631 DCHECK(!callee->AsProperty()->IsSuperAccess());
2636 __ push(Operand(
esp, 0));
2645 Expression* callee = expr->expression();
2646 DCHECK(callee->IsProperty());
2647 Property* prop = callee->AsProperty();
2648 DCHECK(prop->IsSuperAccess());
2651 Literal* key = prop->key()->AsLiteral();
2652 DCHECK(!key->value()->IsSmi());
2654 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference();
2661 __ push(Immediate(key->value()));
2668 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2676 EmitCall(expr, CallICState::METHOD);
2686 Expression* callee = expr->expression();
2689 DCHECK(callee->IsProperty());
2696 __ push(Operand(
esp, 0));
2699 EmitCall(expr, CallICState::METHOD);
2705 ZoneList<Expression*>* args = expr->arguments();
2706 int arg_count = args->length();
2707 { PreservePositionScope
scope(
masm()->positions_recorder());
2708 for (
int i = 0;
i < arg_count;
i++) {
2716 isolate(), arg_count, call_type);
2734 if (arg_count > 0) {
2737 __ push(Immediate(isolate()->factory()->undefined_value()));
2749 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2753 void FullCodeGenerator::VisitCall(Call* expr) {
2757 expr->return_is_recorded_ =
false;
2760 Comment cmnt(
masm_,
"[ Call");
2761 Expression* callee = expr->expression();
2762 Call::CallType call_type = expr->GetCallType(isolate());
2764 if (call_type == Call::POSSIBLY_EVAL_CALL) {
2768 ZoneList<Expression*>* args = expr->arguments();
2769 int arg_count = args->length();
2770 { PreservePositionScope pos_scope(
masm()->positions_recorder());
2773 __ push(Immediate(isolate()->factory()->undefined_value()));
2775 for (
int i = 0;
i < arg_count;
i++) {
2799 }
else if (call_type == Call::GLOBAL_CALL) {
2802 }
else if (call_type == Call::LOOKUP_SLOT_CALL) {
2804 VariableProxy* proxy = callee->AsVariableProxy();
2806 { PreservePositionScope
scope(
masm()->positions_recorder());
2815 __ push(Immediate(proxy->name()));
2816 __ CallRuntime(Runtime::kLoadLookupSlot, 2);
2822 if (done.is_linked()) {
2824 __ jmp(&call, Label::kNear);
2830 __ push(Immediate(isolate()->factory()->undefined_value()));
2838 }
else if (call_type == Call::PROPERTY_CALL) {
2839 Property*
property = callee->AsProperty();
2840 bool is_named_call =
property->key()->IsPropertyName();
2842 if (property->IsSuperAccess() && is_named_call) {
2846 PreservePositionScope
scope(
masm()->positions_recorder());
2849 if (is_named_call) {
2856 DCHECK(call_type == Call::OTHER_CALL);
2858 { PreservePositionScope
scope(
masm()->positions_recorder());
2861 __ push(Immediate(isolate()->factory()->undefined_value()));
2868 DCHECK(expr->return_is_recorded_);
2873 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
2874 Comment cmnt(
masm_,
"[ CallNew");
2885 ZoneList<Expression*>* args = expr->arguments();
2886 int arg_count = args->length();
2887 for (
int i = 0;
i < arg_count;
i++) {
2896 __ Move(
eax, Immediate(arg_count));
2900 if (FLAG_pretenuring_call_new) {
2902 DCHECK(expr->AllocationSiteFeedbackSlot() ==
2903 expr->CallNewFeedbackSlot() + 1);
2916 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
2917 ZoneList<Expression*>* args = expr->arguments();
2918 DCHECK(args->length() == 1);
2922 Label materialize_true, materialize_false;
2923 Label* if_true =
NULL;
2924 Label* if_false =
NULL;
2925 Label* fall_through =
NULL;
2926 context()->PrepareTest(&materialize_true, &materialize_false,
2927 &if_true, &if_false, &fall_through);
2931 Split(
zero, if_true, if_false, fall_through);
2933 context()->Plug(if_true, if_false);
2937 void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
2938 ZoneList<Expression*>* args = expr->arguments();
2939 DCHECK(args->length() == 1);
2943 Label materialize_true, materialize_false;
2944 Label* if_true =
NULL;
2945 Label* if_false =
NULL;
2946 Label* fall_through =
NULL;
2947 context()->PrepareTest(&materialize_true, &materialize_false,
2948 &if_true, &if_false, &fall_through);
2952 Split(
zero, if_true, if_false, fall_through);
2954 context()->Plug(if_true, if_false);
2958 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
2959 ZoneList<Expression*>* args = expr->arguments();
2960 DCHECK(args->length() == 1);
2964 Label materialize_true, materialize_false;
2965 Label* if_true =
NULL;
2966 Label* if_false =
NULL;
2967 Label* fall_through =
NULL;
2968 context()->PrepareTest(&materialize_true, &materialize_false,
2969 &if_true, &if_false, &fall_through);
2971 __ JumpIfSmi(
eax, if_false);
2972 __ cmp(
eax, isolate()->factory()->null_value());
2986 context()->Plug(if_true, if_false);
2990 void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) {
2991 ZoneList<Expression*>* args = expr->arguments();
2992 DCHECK(args->length() == 1);
2996 Label materialize_true, materialize_false;
2997 Label* if_true =
NULL;
2998 Label* if_false =
NULL;
2999 Label* fall_through =
NULL;
3000 context()->PrepareTest(&materialize_true, &materialize_false,
3001 &if_true, &if_false, &fall_through);
3003 __ JumpIfSmi(
eax, if_false);
3008 context()->Plug(if_true, if_false);
3012 void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) {
3013 ZoneList<Expression*>* args = expr->arguments();
3014 DCHECK(args->length() == 1);
3018 Label materialize_true, materialize_false;
3019 Label* if_true =
NULL;
3020 Label* if_false =
NULL;
3021 Label* fall_through =
NULL;
3022 context()->PrepareTest(&materialize_true, &materialize_false,
3023 &if_true, &if_false, &fall_through);
3025 __ JumpIfSmi(
eax, if_false);
3032 context()->Plug(if_true, if_false);
3036 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
3037 CallRuntime* expr) {
3038 ZoneList<Expression*>* args = expr->arguments();
3039 DCHECK(args->length() == 1);
3043 Label materialize_true, materialize_false, skip_lookup;
3044 Label* if_true =
NULL;
3045 Label* if_false =
NULL;
3046 Label* fall_through =
NULL;
3047 context()->PrepareTest(&materialize_true, &materialize_false,
3048 &if_true, &if_false, &fall_through);
3050 __ AssertNotSmi(
eax);
3062 __ cmp(
ecx, isolate()->factory()->hash_table_map());
3068 Label entry, loop, done;
3071 __ NumberOfOwnDescriptors(
ecx,
ebx);
3075 __ LoadInstanceDescriptors(
ebx,
ebx);
3091 __ cmp(
edx, isolate()->factory()->value_of_string());
3107 __ bind(&skip_lookup);
3112 __ JumpIfSmi(
ecx, if_false);
3121 Split(
equal, if_true, if_false, fall_through);
3123 context()->Plug(if_true, if_false);
3127 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
3128 ZoneList<Expression*>* args = expr->arguments();
3129 DCHECK(args->length() == 1);
3133 Label materialize_true, materialize_false;
3134 Label* if_true =
NULL;
3135 Label* if_false =
NULL;
3136 Label* fall_through =
NULL;
3137 context()->PrepareTest(&materialize_true, &materialize_false,
3138 &if_true, &if_false, &fall_through);
3140 __ JumpIfSmi(
eax, if_false);
3143 Split(
equal, if_true, if_false, fall_through);
3145 context()->Plug(if_true, if_false);
3149 void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
3150 ZoneList<Expression*>* args = expr->arguments();
3151 DCHECK(args->length() == 1);
3155 Label materialize_true, materialize_false;
3156 Label* if_true =
NULL;
3157 Label* if_false =
NULL;
3158 Label* fall_through =
NULL;
3159 context()->PrepareTest(&materialize_true, &materialize_false,
3160 &if_true, &if_false, &fall_through);
3170 Split(
equal, if_true, if_false, fall_through);
3172 context()->Plug(if_true, if_false);
3177 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
3178 ZoneList<Expression*>* args = expr->arguments();
3179 DCHECK(args->length() == 1);
3183 Label materialize_true, materialize_false;
3184 Label* if_true =
NULL;
3185 Label* if_false =
NULL;
3186 Label* fall_through =
NULL;
3187 context()->PrepareTest(&materialize_true, &materialize_false,
3188 &if_true, &if_false, &fall_through);
3190 __ JumpIfSmi(
eax, if_false);
3193 Split(
equal, if_true, if_false, fall_through);
3195 context()->Plug(if_true, if_false);
3199 void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
3200 ZoneList<Expression*>* args = expr->arguments();
3201 DCHECK(args->length() == 1);
3205 Label materialize_true, materialize_false;
3206 Label* if_true =
NULL;
3207 Label* if_false =
NULL;
3208 Label* fall_through =
NULL;
3209 context()->PrepareTest(&materialize_true, &materialize_false,
3210 &if_true, &if_false, &fall_through);
3212 __ JumpIfSmi(
eax, if_false);
3215 Split(
equal, if_true, if_false, fall_through);
3217 context()->Plug(if_true, if_false);
3222 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
3223 DCHECK(expr->arguments()->length() == 0);
3225 Label materialize_true, materialize_false;
3226 Label* if_true =
NULL;
3227 Label* if_false =
NULL;
3228 Label* fall_through =
NULL;
3229 context()->PrepareTest(&materialize_true, &materialize_false,
3230 &if_true, &if_false, &fall_through);
3236 Label check_frame_marker;
3243 __ bind(&check_frame_marker);
3247 Split(
equal, if_true, if_false, fall_through);
3249 context()->Plug(if_true, if_false);
3253 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
3254 ZoneList<Expression*>* args = expr->arguments();
3255 DCHECK(args->length() == 2);
3261 Label materialize_true, materialize_false;
3262 Label* if_true =
NULL;
3263 Label* if_false =
NULL;
3264 Label* fall_through =
NULL;
3265 context()->PrepareTest(&materialize_true, &materialize_false,
3266 &if_true, &if_false, &fall_through);
3271 Split(
equal, if_true, if_false, fall_through);
3273 context()->Plug(if_true, if_false);
3277 void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
3278 ZoneList<Expression*>* args = expr->arguments();
3279 DCHECK(args->length() == 1);
3292 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
3293 DCHECK(expr->arguments()->length() == 0);
3315 void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
3316 ZoneList<Expression*>* args = expr->arguments();
3317 DCHECK(args->length() == 1);
3318 Label done,
null,
function, non_function_constructor;
3323 __ JumpIfSmi(
eax, &
null);
3357 __ mov(
eax, isolate()->factory()->Function_string());
3361 __ bind(&non_function_constructor);
3362 __ mov(
eax, isolate()->factory()->Object_string());
3367 __ mov(
eax, isolate()->factory()->null_value());
3376 void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
3378 SubStringStub stub(isolate());
3379 ZoneList<Expression*>* args = expr->arguments();
3380 DCHECK(args->length() == 3);
3389 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
3391 RegExpExecStub stub(isolate());
3392 ZoneList<Expression*>* args = expr->arguments();
3393 DCHECK(args->length() == 4);
3403 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
3404 ZoneList<Expression*>* args = expr->arguments();
3405 DCHECK(args->length() == 1);
3411 __ JumpIfSmi(
eax, &done, Label::kNear);
3422 void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
3423 ZoneList<Expression*>* args = expr->arguments();
3424 DCHECK(args->length() == 2);
3426 Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
3430 Label runtime, done, not_date_object;
3431 Register
object =
eax;
3432 Register result =
eax;
3433 Register scratch =
ecx;
3435 __ JumpIfSmi(
object, ¬_date_object);
3439 if (index->value() == 0) {
3444 ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
3445 __ mov(scratch, Operand::StaticVariable(stamp));
3453 __ PrepareCallCFunction(2, scratch);
3454 __ mov(Operand(
esp, 0),
object);
3456 __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
3460 __ bind(¬_date_object);
3461 __ CallRuntime(Runtime::kThrowNotDateError, 0);
3467 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
3468 ZoneList<Expression*>* args = expr->arguments();
3471 Register
string =
eax;
3472 Register index =
ebx;
3473 Register value =
ecx;
3482 if (FLAG_debug_code) {
3484 __ Check(
zero, kNonSmiValue);
3486 __ Check(
zero, kNonSmiValue);
3492 if (FLAG_debug_code) {
3494 __ EmitSeqStringSetCharCheck(
string, index, value, one_byte_seq_type);
3503 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
3504 ZoneList<Expression*>* args = expr->arguments();
3507 Register
string =
eax;
3508 Register index =
ebx;
3509 Register value =
ecx;
3517 if (FLAG_debug_code) {
3519 __ Check(
zero, kNonSmiValue);
3521 __ Check(
zero, kNonSmiValue);
3524 __ EmitSeqStringSetCharCheck(
string, index, value, two_byte_seq_type);
3536 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
3538 ZoneList<Expression*>* args = expr->arguments();
3539 DCHECK(args->length() == 2);
3543 __ CallRuntime(Runtime::kMathPowSlow, 2);
3548 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) {
3549 ZoneList<Expression*>* args = expr->arguments();
3550 DCHECK(args->length() == 2);
3558 __ JumpIfSmi(
ebx, &done, Label::kNear);
3577 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
3578 ZoneList<Expression*>* args = expr->arguments();
3584 NumberToStringStub stub(isolate());
3590 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
3591 ZoneList<Expression*>* args = expr->arguments();
3592 DCHECK(args->length() == 1);
3597 StringCharFromCodeGenerator generator(
eax,
ebx);
3598 generator.GenerateFast(
masm_);
3601 NopRuntimeCallHelper call_helper;
3602 generator.GenerateSlow(
masm_, call_helper);
3609 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
3610 ZoneList<Expression*>* args = expr->arguments();
3611 DCHECK(args->length() == 2);
3616 Register
object =
ebx;
3617 Register index =
eax;
3618 Register result =
edx;
3622 Label need_conversion;
3623 Label index_out_of_range;
3625 StringCharCodeAtGenerator generator(
object,
3630 &index_out_of_range,
3632 generator.GenerateFast(
masm_);
3635 __ bind(&index_out_of_range);
3638 __ Move(result, Immediate(isolate()->factory()->nan_value()));
3641 __ bind(&need_conversion);
3644 __ Move(result, Immediate(isolate()->factory()->undefined_value()));
3647 NopRuntimeCallHelper call_helper;
3648 generator.GenerateSlow(
masm_, call_helper);
3655 void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
3656 ZoneList<Expression*>* args = expr->arguments();
3657 DCHECK(args->length() == 2);
3662 Register
object =
ebx;
3663 Register index =
eax;
3664 Register scratch =
edx;
3665 Register result =
eax;
3669 Label need_conversion;
3670 Label index_out_of_range;
3672 StringCharAtGenerator generator(
object,
3678 &index_out_of_range,
3680 generator.GenerateFast(
masm_);
3683 __ bind(&index_out_of_range);
3686 __ Move(result, Immediate(isolate()->factory()->empty_string()));
3689 __ bind(&need_conversion);
3695 NopRuntimeCallHelper call_helper;
3696 generator.GenerateSlow(
masm_, call_helper);
3703 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
3704 ZoneList<Expression*>* args = expr->arguments();
3716 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
3717 ZoneList<Expression*>* args = expr->arguments();
3723 StringCompareStub stub(isolate());
3729 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
3730 ZoneList<Expression*>* args = expr->arguments();
3731 DCHECK(args->length() >= 2);
3733 int arg_count = args->length() - 2;
3734 for (
int i = 0;
i < arg_count + 1; ++
i) {
3739 Label runtime, done;
3741 __ JumpIfSmi(
eax, &runtime);
3747 ParameterCount count(arg_count);
3754 __ CallRuntime(Runtime::kCall, args->length());
3761 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
3763 RegExpConstructResultStub stub(isolate());
3764 ZoneList<Expression*>* args = expr->arguments();
3765 DCHECK(args->length() == 3);
3776 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
3777 ZoneList<Expression*>* args = expr->arguments();
3781 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value();
3783 Handle<FixedArray> jsfunction_result_caches(
3784 isolate()->native_context()->jsfunction_result_caches());
3785 if (jsfunction_result_caches->length() <= cache_id) {
3786 __ Abort(kAttemptToUseUndefinedCache);
3787 __ mov(
eax, isolate()->factory()->undefined_value());
3795 Register cache =
ebx;
3804 Label done, not_found;
3814 __ bind(¬_found);
3818 __ CallRuntime(Runtime::kGetFromCache, 2);
3825 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
3826 ZoneList<Expression*>* args = expr->arguments();
3827 DCHECK(args->length() == 1);
3831 __ AssertString(
eax);
3833 Label materialize_true, materialize_false;
3834 Label* if_true =
NULL;
3835 Label* if_false =
NULL;
3836 Label* fall_through =
NULL;
3837 context()->PrepareTest(&materialize_true, &materialize_false,
3838 &if_true, &if_false, &fall_through);
3843 Split(
zero, if_true, if_false, fall_through);
3845 context()->Plug(if_true, if_false);
3849 void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
3850 ZoneList<Expression*>* args = expr->arguments();
3851 DCHECK(args->length() == 1);
3854 __ AssertString(
eax);
3863 void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) {
3864 Label bailout, done, one_char_separator, long_separator,
3865 non_trivial_array, not_size_one_array, loop,
3866 loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry;
3868 ZoneList<Expression*>* args = expr->arguments();
3869 DCHECK(args->length() == 2);
3875 Register array =
eax;
3876 Register elements =
no_reg;
3878 Register index =
edx;
3880 Register string_length =
ecx;
3882 Register
string =
esi;
3884 Register scratch =
ebx;
3886 Register array_length =
edi;
3887 Register result_pos =
no_reg;
3892 Operand array_length_operand = Operand(
esp, 0);
3896 __ JumpIfSmi(array, &bailout);
3901 __ CheckFastElements(scratch, &bailout);
3905 __ SmiUntag(array_length);
3907 __ mov(result_operand, isolate()->factory()->empty_string());
3911 __ bind(&non_trivial_array);
3912 __ mov(array_length_operand, array_length);
3923 __ Move(index, Immediate(0));
3924 __ Move(string_length, Immediate(0));
3929 __ cmp(index, array_length);
3930 __ Assert(
less, kNoEmptyArraysHereInEmitFastOneByteArrayJoin);
3937 __ JumpIfSmi(
string, &bailout);
3940 __ and_(scratch, Immediate(
3944 __ add(string_length,
3947 __ add(index, Immediate(1));
3948 __ cmp(index, array_length);
3952 __ cmp(array_length, 1);
3955 __ mov(result_operand, scratch);
3958 __ bind(¬_size_one_array);
3961 result_pos = array_length;
3969 __ mov(
string, separator_operand);
3970 __ JumpIfSmi(
string, &bailout);
3973 __ and_(scratch, Immediate(
3980 __ mov(scratch, separator_operand);
3982 __ sub(string_length, scratch);
3983 __ imul(scratch, array_length_operand);
3985 __ add(string_length, scratch);
3988 __ shr(string_length, 1);
3992 __ AllocateOneByteString(result_pos, string_length, scratch, index,
string,
3994 __ mov(result_operand, result_pos);
3998 __ mov(
string, separator_operand);
4001 __ j(
equal, &one_char_separator);
4006 __ mov(index, Immediate(0));
4007 __ jmp(&loop_1_condition);
4020 __ mov(string_length,
4022 __ shr(string_length, 1);
4025 __ CopyBytes(
string, result_pos, string_length, scratch);
4026 __ add(index, Immediate(1));
4027 __ bind(&loop_1_condition);
4028 __ cmp(index, array_length_operand);
4035 __ bind(&one_char_separator);
4038 __ mov_b(separator_operand, scratch);
4040 __ Move(index, Immediate(0));
4043 __ jmp(&loop_2_entry);
4052 __ mov_b(scratch, separator_operand);
4053 __ mov_b(Operand(result_pos, 0), scratch);
4056 __ bind(&loop_2_entry);
4061 __ mov(string_length,
4063 __ shr(string_length, 1);
4066 __ CopyBytes(
string, result_pos, string_length, scratch);
4067 __ add(index, Immediate(1));
4069 __ cmp(index, array_length_operand);
4075 __ bind(&long_separator);
4077 __ Move(index, Immediate(0));
4080 __ jmp(&loop_3_entry);
4089 __ mov(
string, separator_operand);
4090 __ mov(string_length,
4092 __ shr(string_length, 1);
4095 __ CopyBytes(
string, result_pos, string_length, scratch);
4097 __ bind(&loop_3_entry);
4102 __ mov(string_length,
4104 __ shr(string_length, 1);
4107 __ CopyBytes(
string, result_pos, string_length, scratch);
4108 __ add(index, Immediate(1));
4110 __ cmp(index, array_length_operand);
4116 __ mov(result_operand, isolate()->factory()->undefined_value());
4118 __ mov(
eax, result_operand);
4127 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
4128 DCHECK(expr->arguments()->length() == 0);
4129 ExternalReference debug_is_active =
4130 ExternalReference::debug_is_active_address(isolate());
4131 __ movzx_b(
eax, Operand::StaticVariable(debug_is_active));
4137 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
4138 if (expr->function() !=
NULL &&
4140 Comment cmnt(
masm_,
"[ InlineRuntimeCall");
4145 Comment cmnt(
masm_,
"[ CallRuntime");
4146 ZoneList<Expression*>* args = expr->arguments();
4148 if (expr->is_jsruntime()) {
4156 if (FLAG_vector_ics) {
4158 Immediate(
Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
4165 __ push(Operand(
esp, 0));
4169 ZoneList<Expression*>* args = expr->arguments();
4170 int arg_count = args->length();
4171 for (
int i = 0;
i < arg_count;
i++) {
4186 int arg_count = args->length();
4187 for (
int i = 0;
i < arg_count;
i++) {
4192 __ CallRuntime(expr->function(), arg_count);
4199 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
4200 switch (expr->op()) {
4201 case Token::DELETE: {
4202 Comment cmnt(
masm_,
"[ UnaryOperation (DELETE)");
4203 Property*
property = expr->expression()->AsProperty();
4204 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4206 if (property !=
NULL) {
4212 }
else if (proxy !=
NULL) {
4213 Variable* var = proxy->var();
4217 if (var->IsUnallocated()) {
4219 __ push(Immediate(var->name()));
4223 }
else if (var->IsStackAllocated() || var->IsContextSlot()) {
4227 context()->Plug(var->is_this());
4232 __ push(Immediate(var->name()));
4233 __ CallRuntime(Runtime::kDeleteLookupSlot, 2);
4246 Comment cmnt(
masm_,
"[ UnaryOperation (VOID)");
4248 context()->Plug(isolate()->factory()->undefined_value());
4253 Comment cmnt(
masm_,
"[ UnaryOperation (NOT)");
4258 }
else if (
context()->IsTest()) {
4262 test->false_label(),
4264 test->fall_through());
4265 context()->Plug(test->true_label(), test->false_label());
4272 Label materialize_true, materialize_false, done;
4277 __ bind(&materialize_true);
4279 if (
context()->IsAccumulatorValue()) {
4280 __ mov(
eax, isolate()->factory()->true_value());
4282 __ Push(isolate()->factory()->true_value());
4284 __ jmp(&done, Label::kNear);
4285 __ bind(&materialize_false);
4287 if (
context()->IsAccumulatorValue()) {
4288 __ mov(
eax, isolate()->factory()->false_value());
4290 __ Push(isolate()->factory()->false_value());
4297 case Token::TYPEOF: {
4298 Comment cmnt(
masm_,
"[ UnaryOperation (TYPEOF)");
4299 { StackValueContext
context(
this);
4302 __ CallRuntime(Runtime::kTypeof, 1);
4313 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
4314 DCHECK(expr->expression()->IsValidReferenceExpression());
4316 Comment cmnt(
masm_,
"[ CountOperation");
4323 Property* prop = expr->expression()->AsProperty();
4329 if (prop->IsSuperAccess()) {
4331 VisitSuperReference(prop->obj()->AsSuperReference());
4338 DCHECK(expr->expression()->AsVariableProxy()->var() !=
NULL);
4339 AccumulatorValueContext
context(
this);
4343 if (expr->is_postfix() && !
context()->IsEffect()) {
4370 Label done, stub_call;
4371 JumpPatchSite patch_site(
masm_);
4374 patch_site.EmitJumpIfNotSmi(
eax, &slow, Label::kNear);
4377 if (expr->is_postfix()) {
4382 switch (assign_type) {
4396 if (expr->op() == Token::INC) {
4403 if (expr->op() == Token::INC) {
4408 __ jmp(&stub_call, Label::kNear);
4411 ToNumberStub convert_stub(isolate());
4412 __ CallStub(&convert_stub);
4415 if (expr->is_postfix()) {
4420 switch (assign_type) {
4438 __ bind(&stub_call);
4441 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
4443 CallIC(code, expr->CountBinOpFeedbackId());
4444 patch_site.EmitPatchInfo();
4448 switch (assign_type) {
4450 if (expr->is_postfix()) {
4452 { EffectContext
context(
this);
4473 prop->key()->AsLiteral()->value());
4477 if (expr->is_postfix()) {
4490 CodeFactory::KeyedStoreIC(isolate(),
strict_mode()).code();
4491 CallIC(ic, expr->CountStoreFeedbackId());
4493 if (expr->is_postfix()) {
4508 VariableProxy* proxy = expr->AsVariableProxy();
4512 if (proxy !=
NULL && proxy->var()->IsUnallocated()) {
4513 Comment cmnt(
masm_,
"[ Global variable");
4516 if (FLAG_vector_ics) {
4518 Immediate(
Smi::FromInt(proxy->VariableFeedbackSlot())));
4525 }
else if (proxy !=
NULL && proxy->var()->IsLookupSlot()) {
4526 Comment cmnt(
masm_,
"[ Lookup slot");
4535 __ push(Immediate(proxy->name()));
4536 __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2);
4549 Expression* sub_expr,
4550 Handle<String> check) {
4551 Label materialize_true, materialize_false;
4552 Label* if_true =
NULL;
4553 Label* if_false =
NULL;
4554 Label* fall_through =
NULL;
4555 context()->PrepareTest(&materialize_true, &materialize_false,
4556 &if_true, &if_false, &fall_through);
4558 { AccumulatorValueContext
context(
this);
4563 Factory* factory = isolate()->factory();
4565 __ JumpIfSmi(
eax, if_true);
4567 isolate()->factory()->heap_number_map());
4568 Split(
equal, if_true, if_false, fall_through);
4570 __ JumpIfSmi(
eax, if_false);
4576 Split(
zero, if_true, if_false, fall_through);
4578 __ JumpIfSmi(
eax, if_false);
4580 Split(
equal, if_true, if_false, fall_through);
4582 __ cmp(
eax, isolate()->factory()->true_value());
4584 __ cmp(
eax, isolate()->factory()->false_value());
4585 Split(
equal, if_true, if_false, fall_through);
4587 __ cmp(
eax, isolate()->factory()->undefined_value());
4589 __ JumpIfSmi(
eax, if_false);
4596 __ JumpIfSmi(
eax, if_false);
4601 Split(
equal, if_true, if_false, fall_through);
4603 __ JumpIfSmi(
eax, if_false);
4604 __ cmp(
eax, isolate()->factory()->null_value());
4613 Split(
zero, if_true, if_false, fall_through);
4615 if (if_false != fall_through)
__ jmp(if_false);
4617 context()->Plug(if_true, if_false);
4621 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
4622 Comment cmnt(
masm_,
"[ CompareOperation");
4631 Label materialize_true, materialize_false;
4632 Label* if_true =
NULL;
4633 Label* if_false =
NULL;
4634 Label* fall_through =
NULL;
4635 context()->PrepareTest(&materialize_true, &materialize_false,
4636 &if_true, &if_false, &fall_through);
4645 __ cmp(
eax, isolate()->factory()->true_value());
4646 Split(
equal, if_true, if_false, fall_through);
4649 case Token::INSTANCEOF: {
4656 Split(
zero, if_true, if_false, fall_through);
4666 JumpPatchSite patch_site(
masm_);
4667 if (inline_smi_code) {
4671 patch_site.EmitJumpIfNotSmi(
ecx, &slow_case, Label::kNear);
4674 __ bind(&slow_case);
4679 Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code();
4680 CallIC(ic, expr->CompareOperationFeedbackId());
4681 patch_site.EmitPatchInfo();
4685 Split(
cc, if_true, if_false, fall_through);
4691 context()->Plug(if_true, if_false);
4696 Expression* sub_expr,
4698 Label materialize_true, materialize_false;
4699 Label* if_true =
NULL;
4700 Label* if_false =
NULL;
4701 Label* fall_through =
NULL;
4702 context()->PrepareTest(&materialize_true, &materialize_false,
4703 &if_true, &if_false, &fall_through);
4709 ? isolate()->factory()->null_value()
4710 : isolate()->factory()->undefined_value();
4711 if (expr->op() == Token::EQ_STRICT) {
4712 __ cmp(
eax, nil_value);
4713 Split(
equal, if_true, if_false, fall_through);
4716 CallIC(ic, expr->CompareOperationFeedbackId());
4720 context()->Plug(if_true, if_false);
4724 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4742 __ mov(Operand(
ebp, frame_offset), value);
4753 if (declaration_scope->is_global_scope() ||
4754 declaration_scope->is_module_scope()) {
4760 }
else if (declaration_scope->is_eval_scope()) {
4766 DCHECK(declaration_scope->is_function_scope());
4789 ExternalReference pending_message_obj =
4790 ExternalReference::address_of_pending_message_obj(isolate());
4791 __ mov(
edx, Operand::StaticVariable(pending_message_obj));
4794 ExternalReference has_pending_message =
4795 ExternalReference::address_of_has_pending_message(isolate());
4796 __ mov(
edx, Operand::StaticVariable(has_pending_message));
4800 ExternalReference pending_message_script =
4801 ExternalReference::address_of_pending_message_script(isolate());
4802 __ mov(
edx, Operand::StaticVariable(pending_message_script));
4811 ExternalReference pending_message_script =
4812 ExternalReference::address_of_pending_message_script(isolate());
4813 __ mov(Operand::StaticVariable(pending_message_script),
edx);
4817 ExternalReference has_pending_message =
4818 ExternalReference::address_of_has_pending_message(isolate());
4819 __ mov(Operand::StaticVariable(has_pending_message),
edx);
4822 ExternalReference pending_message_obj =
4823 ExternalReference::address_of_pending_message_obj(isolate());
4824 __ mov(Operand::StaticVariable(pending_message_obj),
edx);
4839 #define __ ACCESS_MASM(masm())
4843 int* context_length) {
4850 __ Drop(*stack_depth);
4851 if (*context_length > 0) {
4857 __ call(finally_entry_);
4860 *context_length = 0;
4867 static const byte kJnsInstruction = 0x79;
4868 static const byte kJnsOffset = 0x11;
4869 static const byte kNopByteOne = 0x66;
4870 static const byte kNopByteTwo = 0x90;
4872 static const byte kCallInstruction = 0xe8;
4878 BackEdgeState target_state,
4879 Code* replacement_code) {
4881 Address jns_instr_address = call_target_address - 3;
4882 Address jns_offset_address = call_target_address - 2;
4884 switch (target_state) {
4890 *jns_instr_address = kJnsInstruction;
4891 *jns_offset_address = kJnsOffset;
4893 case ON_STACK_REPLACEMENT:
4894 case OSR_AFTER_STACK_CHECK:
4900 *jns_instr_address = kNopByteOne;
4901 *jns_offset_address = kNopByteTwo;
4907 replacement_code->entry());
4908 unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch(
4909 unoptimized_code, call_target_address, replacement_code);
4915 Code* unoptimized_code,
4918 Address jns_instr_address = call_target_address - 3;
4919 DCHECK_EQ(kCallInstruction, *(call_target_address - 1));
4921 if (*jns_instr_address == kJnsInstruction) {
4922 DCHECK_EQ(kJnsOffset, *(call_target_address - 2));
4923 DCHECK_EQ(isolate->builtins()->InterruptCheck()->entry(),
4929 DCHECK_EQ(kNopByteOne, *jns_instr_address);
4930 DCHECK_EQ(kNopByteTwo, *(call_target_address - 2));
4933 isolate->builtins()->OnStackReplacement()->entry()) {
4934 return ON_STACK_REPLACEMENT;
4937 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4940 return OSR_AFTER_STACK_CHECK;
static const int kLengthOffset
Isolate * isolate() const
static Address target_address_at(Address pc, ConstantPoolArray *constant_pool)
static void set_target_address_at(Address pc, ConstantPoolArray *constant_pool, Address target, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
static const int kJSReturnSequenceLength
int SizeOfCodeGeneratedSince(Label *label)
static void PatchAt(Code *unoptimized_code, Address pc, BackEdgeState target_state, Code *replacement_code)
static BackEdgeState GetBackEdgeState(Isolate *isolate, Code *unoptimized_code, Address pc_after)
static BailoutId Declarations()
static BailoutId FunctionEntry()
static Handle< Code > initialize_stub(Isolate *isolate, int argc, CallICState::CallType call_type)
static const int kValueOffset
static Condition ComputeCondition(Token::Value op)
static Handle< Code > GetUninitialized(Isolate *isolate, NilValue nil)
bool IsOptimizable() const
bool ShouldSelfOptimize()
void AddNoFrameRange(int from, int to)
static bool IsCompileTimeValue(Expression *expression)
static Handle< SharedFunctionInfo > BuildFunctionInfo(FunctionLiteral *node, Handle< Script > script, CompilationInfo *outer)
@ STRING_FUNCTION_PROTOTYPE_MAP_INDEX
@ JSFUNCTION_RESULT_CACHES_INDEX
static int SlotOffset(int index)
static const int kDescriptorSize
static const int kEnumCacheBridgeCacheOffset
static const int kEnumCacheOffset
static const int kFirstOffset
static const int kMaximumClonedProperties
static const int kLengthOffset
static const int kHeaderSize
static int OffsetOfElementAt(int index)
virtual void DropAndPlug(int count, Register reg) const
virtual void Plug(bool flag) const
virtual void DropAndPlug(int count, Register reg) const
virtual void Plug(bool flag) const
virtual void DropAndPlug(int count, Register reg) const
virtual void Plug(bool flag) const
virtual void DropAndPlug(int count, Register reg) const
static const TestContext * cast(const ExpressionContext *context)
virtual void Plug(bool flag) const
virtual NestedStatement * Exit(int *stack_depth, int *context_length)
static const int kMaxBackEdgeWeight
void EmitAccessor(Expression *expression)
void Split(Condition cc, Label *if_true, Label *if_false, Label *fall_through)
void EmitBinaryOp(BinaryOperation *expr, Token::Value op, OverwriteMode mode)
void EmitLiteralCompareTypeof(Expression *expr, Expression *sub_expr, Handle< String > check)
void VisitDeclarations(ZoneList< Declaration * > *declarations)
void PrepareForBailoutForId(BailoutId id, State state)
void EmitNewClosure(Handle< SharedFunctionInfo > info, bool pretenure)
void GetVar(Register destination, Variable *var)
static Register context_register()
ZoneList< Handle< Object > > * globals_
void VisitForControl(Expression *expr, Label *if_true, Label *if_false, Label *fall_through)
void PushFunctionArgumentForContextAllocation()
void CallLoadIC(ContextualMode mode, TypeFeedbackId id=TypeFeedbackId::None())
bool generate_debug_code_
void RecordBackEdge(BailoutId osr_ast_id)
MemOperand StackOperand(Variable *var)
void EmitVariableLoad(VariableProxy *proxy)
friend class NestedStatement
void EmitReturnSequence()
void SetVar(Variable *var, Register source, Register scratch0, Register scratch1)
MemOperand ContextSlotOperandCheckExtensions(Variable *var, Label *slow)
void EmitKeyedPropertyAssignment(Assignment *expr)
void DeclareGlobals(Handle< FixedArray > pairs)
void EmitResolvePossiblyDirectEval(int arg_count)
void VisitForStackValue(Expression *expr)
void EmitKeyedCallWithLoadIC(Call *expr, Expression *key)
void EmitProfilingCounterReset()
void EmitKeyedPropertyLoad(Property *expr)
void EmitDebugCheckDeclarationContext(Variable *variable)
void EmitUnwindBeforeReturn()
FunctionLiteral * function()
void EmitNamedSuperPropertyLoad(Property *expr)
Handle< Cell > profiling_counter_
bool TryLiteralCompare(CompareOperation *compare)
void increment_loop_depth()
void SetStatementPosition(Statement *stmt)
Handle< FixedArray > FeedbackVector()
void StoreToFrameField(int frame_offset, Register value)
void LoadContextField(Register dst, int context_index)
const ExpressionContext * context()
void EmitNamedPropertyLoad(Property *expr)
void EmitBackEdgeBookkeeping(IterationStatement *stmt, Label *back_edge_target)
void DoTest(Expression *condition, Label *if_true, Label *if_false, Label *fall_through)
void VisitForAccumulatorValue(Expression *expr)
void PrepareForBailout(Expression *node, State state)
void CallStoreIC(TypeFeedbackId id=TypeFeedbackId::None())
MemOperand VarOperand(Variable *var, Register scratch)
void DeclareModules(Handle< FixedArray > descriptions)
void EmitGeneratorResume(Expression *generator, Expression *value, JSGeneratorObject::ResumeMode resume_mode)
void VisitForEffect(Expression *expr)
void EmitAssignment(Expression *expr)
void EmitCall(Call *expr, CallICState::CallType=CallICState::FUNCTION)
void SetFunctionPosition(FunctionLiteral *fun)
int DeclareGlobalsFlags()
void EmitLoadHomeObject(SuperReference *expr)
void EmitStoreToStackLocalOrContextSlot(Variable *var, MemOperand location)
void decrement_loop_depth()
void EmitInlineSmiBinaryOp(BinaryOperation *expr, Token::Value op, OverwriteMode mode, Expression *left, Expression *right)
void EmitLiteralCompareNil(CompareOperation *expr, Expression *sub_expr, NilValue nil)
void EmitVariableAssignment(Variable *var, Token::Value op)
void CallIC(Handle< Code > code, TypeFeedbackId id=TypeFeedbackId::None())
void EmitCreateIteratorResult(bool done)
void EmitLoadGlobalCheckExtensions(VariableProxy *proxy, TypeofState typeof_state, Label *slow)
void EmitCallWithLoadIC(Call *expr)
void EnsureSlotContainsAllocationSite(int slot)
void PrepareForBailoutBeforeSplit(Expression *expr, bool should_normalize, Label *if_true, Label *if_false)
Handle< Script > script()
void EmitInlineRuntimeCall(CallRuntime *expr)
void SetSourcePosition(int pos)
void EmitSuperCallWithLoadIC(Call *expr)
void EmitNamedSuperPropertyAssignment(Assignment *expr)
void EmitNamedPropertyAssignment(Assignment *expr)
Handle< FixedArray > handler_table_
void RecordJSReturnSite(Call *call)
static Register result_register()
void VisitForTypeofValue(Expression *expr)
void EmitDynamicLookupFastCase(VariableProxy *proxy, TypeofState typeof_state, Label *slow, Label *done)
bool ShouldInlineSmiCase(Token::Value op)
Handle< FixedArray > handler_table()
void EmitProfilingCounterDecrement(int delta)
void VisitInDuplicateContext(Expression *expr)
static const int kBuiltinsOffset
static const int kNativeContextOffset
static const int kGlobalProxyOffset
static const int kMapOffset
static const int kLengthOffset
static const int kValueOffset
static const int kCacheStampOffset
static const int kFingerOffset
static const int kSharedFunctionInfoOffset
static const int kLiteralsOffset
static const int kCodeEntryOffset
static const int kResultDonePropertyOffset
static const int kFunctionOffset
static const int kGeneratorClosed
static const int kResultValuePropertyOffset
static const int kGeneratorExecuting
static const int kOperandStackOffset
static const int kReceiverOffset
static const int kContextOffset
static const int kContinuationOffset
static const int kInitialMaxFastElementArray
static const int kPropertiesOffset
static const int kElementsOffset
static const int kInObjectFieldCount
static const int kValueOffset
static const int kLocal0Offset
static const int kFunctionOffset
static const Register ReceiverRegister()
static const Register NameRegister()
Handle< Object > CodeObject()
static const int kIsUndetectable
static const int kBitFieldOffset
static const int kStringWrapperSafeForDefaultValueOf
static const int kInstanceTypeOffset
static const int kBitField2Offset
static const int kConstructorOffset
static const int kPrototypeOffset
static const int kHashFieldOffset
static void MaybeCallEntryHook(MacroAssembler *masm)
static const int kNoPosition
Scope * outer_scope() const
int num_parameters() const
VariableDeclaration * function() const
int ContextChainLength(Scope *scope)
void VisitIllegalRedeclaration(AstVisitor *visitor)
Scope * DeclarationScope()
Variable * arguments() const
Variable * parameter(int index) const
static const int kHeaderSize
static const int kFormalParameterCountOffset
static const int kInstanceClassNameOffset
static Smi * FromInt(int value)
static bool IsValid(intptr_t value)
static const int kContextOffset
static const int kContextOffset
static const int kExpressionsOffset
static const int kCallerSPOffset
static const int kMarkerOffset
static const int kCallerFPOffset
static const Register ReceiverRegister()
static const Register NameRegister()
static const Register ValueRegister()
static const unsigned int kContainsCachedArrayIndexMask
static const int kLengthOffset
bool Equals(String *other)
static Handle< Code > GetUninitialized(Isolate *isolate)
static TypeFeedbackId None()
static Handle< Object > MegamorphicSentinel(Isolate *isolate)
static const Register SlotRegister()
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction pairs(ARM only)") DEFINE_BOOL(enable_unaligned_accesses
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define POINTER_SIZE_ALIGN(value)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
static int Push(SpecialRPOStackFrame *stack, int depth, BasicBlock *child, int unvisited)
Vector< const char > CStrVector(const char *data)
const uint32_t kStringEncodingMask
MemOperand ContextOperand(Register context, int index)
@ DONT_TRACK_ALLOCATION_SITE
kFeedbackVectorOffset kHiddenPrototypeBit kReadOnlyPrototypeBit kDoNotCacheBit kIsTopLevelBit kAllowLazyCompilationWithoutContext has_duplicate_parameters
static LifetimePosition Min(LifetimePosition a, LifetimePosition b)
bool IsDeclaredVariableMode(VariableMode mode)
const uint32_t kTwoByteStringTag
Operand FieldOperand(Register object, int offset)
const uint32_t kStringTag
@ LAST_NONCALLABLE_SPEC_OBJECT_TYPE
@ NUM_OF_CALLABLE_SPEC_OBJECT_TYPES
@ FIRST_NONCALLABLE_SPEC_OBJECT_TYPE
const uint32_t kOneByteStringTag
bool IsImmutableVariableMode(VariableMode mode)
Condition NegateCondition(Condition cond)
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)
const uint32_t kStringRepresentationMask
OStream & dec(OStream &os)
Operand FixedArrayElementOperand(Register array, Register index_as_smi, int additional_offset=0)
kFeedbackVectorOffset flag
MemOperand GlobalObjectOperand()
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
const intptr_t kSmiTagMask
@ RECORD_CONSTRUCTOR_TARGET
const uint32_t kIsNotStringMask
void CopyBytes(uint8_t *target, uint8_t *source)
bool IsFastObjectElementsKind(ElementsKind kind)
Debugger support for the V8 JavaScript engine.