| OLD | NEW | 
|     1 // Copyright 2013 the V8 project authors. All rights reserved. |     1 // Copyright 2013 the V8 project authors. All rights reserved. | 
|     2 // Redistribution and use in source and binary forms, with or without |     2 // Redistribution and use in source and binary forms, with or without | 
|     3 // modification, are permitted provided that the following conditions are |     3 // modification, are permitted provided that the following conditions are | 
|     4 // met: |     4 // met: | 
|     5 // |     5 // | 
|     6 //     * Redistributions of source code must retain the above copyright |     6 //     * Redistributions of source code must retain the above copyright | 
|     7 //       notice, this list of conditions and the following disclaimer. |     7 //       notice, this list of conditions and the following disclaimer. | 
|     8 //     * Redistributions in binary form must reproduce the above |     8 //     * Redistributions in binary form must reproduce the above | 
|     9 //       copyright notice, this list of conditions and the following |     9 //       copyright notice, this list of conditions and the following | 
|    10 //       disclaimer in the documentation and/or other materials provided |    10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    96 void LChunkBuilder::Abort(BailoutReason reason) { |    96 void LChunkBuilder::Abort(BailoutReason reason) { | 
|    97   info()->set_bailout_reason(reason); |    97   info()->set_bailout_reason(reason); | 
|    98   status_ = ABORTED; |    98   status_ = ABORTED; | 
|    99 } |    99 } | 
|   100  |   100  | 
|   101  |   101  | 
|   102 #ifdef _MSC_VER |   102 #ifdef _MSC_VER | 
|   103 void LCodeGen::MakeSureStackPagesMapped(int offset) { |   103 void LCodeGen::MakeSureStackPagesMapped(int offset) { | 
|   104   const int kPageSize = 4 * KB; |   104   const int kPageSize = 4 * KB; | 
|   105   for (offset -= kPageSize; offset > 0; offset -= kPageSize) { |   105   for (offset -= kPageSize; offset > 0; offset -= kPageSize) { | 
|   106     __ movq(Operand(rsp, offset), rax); |   106     __ movp(Operand(rsp, offset), rax); | 
|   107   } |   107   } | 
|   108 } |   108 } | 
|   109 #endif |   109 #endif | 
|   110  |   110  | 
|   111  |   111  | 
|   112 void LCodeGen::SaveCallerDoubles() { |   112 void LCodeGen::SaveCallerDoubles() { | 
|   113   ASSERT(info()->saves_caller_doubles()); |   113   ASSERT(info()->saves_caller_doubles()); | 
|   114   ASSERT(NeedsEagerFrame()); |   114   ASSERT(NeedsEagerFrame()); | 
|   115   Comment(";;; Save clobbered callee double registers"); |   115   Comment(";;; Save clobbered callee double registers"); | 
|   116   int count = 0; |   116   int count = 0; | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   154     } |   154     } | 
|   155 #endif |   155 #endif | 
|   156  |   156  | 
|   157     // Classic mode functions need to replace the receiver with the global proxy |   157     // Classic mode functions need to replace the receiver with the global proxy | 
|   158     // when called as functions (without an explicit receiver object). |   158     // when called as functions (without an explicit receiver object). | 
|   159     if (info_->this_has_uses() && |   159     if (info_->this_has_uses() && | 
|   160         info_->is_classic_mode() && |   160         info_->is_classic_mode() && | 
|   161         !info_->is_native()) { |   161         !info_->is_native()) { | 
|   162       Label ok; |   162       Label ok; | 
|   163       StackArgumentsAccessor args(rsp, scope()->num_parameters()); |   163       StackArgumentsAccessor args(rsp, scope()->num_parameters()); | 
|   164       __ movq(rcx, args.GetReceiverOperand()); |   164       __ movp(rcx, args.GetReceiverOperand()); | 
|   165  |   165  | 
|   166       __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); |   166       __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); | 
|   167       __ j(not_equal, &ok, Label::kNear); |   167       __ j(not_equal, &ok, Label::kNear); | 
|   168  |   168  | 
|   169       __ movq(rcx, GlobalObjectOperand()); |   169       __ movp(rcx, GlobalObjectOperand()); | 
|   170       __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); |   170       __ movp(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); | 
|   171  |   171  | 
|   172       __ movq(args.GetReceiverOperand(), rcx); |   172       __ movp(args.GetReceiverOperand(), rcx); | 
|   173  |   173  | 
|   174       __ bind(&ok); |   174       __ bind(&ok); | 
|   175     } |   175     } | 
|   176   } |   176   } | 
|   177  |   177  | 
|   178   info()->set_prologue_offset(masm_->pc_offset()); |   178   info()->set_prologue_offset(masm_->pc_offset()); | 
|   179   if (NeedsEagerFrame()) { |   179   if (NeedsEagerFrame()) { | 
|   180     ASSERT(!frame_is_built_); |   180     ASSERT(!frame_is_built_); | 
|   181     frame_is_built_ = true; |   181     frame_is_built_ = true; | 
|   182     __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); |   182     __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); | 
|   183     info()->AddNoFrameRange(0, masm_->pc_offset()); |   183     info()->AddNoFrameRange(0, masm_->pc_offset()); | 
|   184   } |   184   } | 
|   185  |   185  | 
|   186   // Reserve space for the stack slots needed by the code. |   186   // Reserve space for the stack slots needed by the code. | 
|   187   int slots = GetStackSlotCount(); |   187   int slots = GetStackSlotCount(); | 
|   188   if (slots > 0) { |   188   if (slots > 0) { | 
|   189     if (FLAG_debug_code) { |   189     if (FLAG_debug_code) { | 
|   190       __ subq(rsp, Immediate(slots * kPointerSize)); |   190       __ subq(rsp, Immediate(slots * kPointerSize)); | 
|   191 #ifdef _MSC_VER |   191 #ifdef _MSC_VER | 
|   192       MakeSureStackPagesMapped(slots * kPointerSize); |   192       MakeSureStackPagesMapped(slots * kPointerSize); | 
|   193 #endif |   193 #endif | 
|   194       __ push(rax); |   194       __ push(rax); | 
|   195       __ Set(rax, slots); |   195       __ Set(rax, slots); | 
|   196       __ movq(kScratchRegister, kSlotsZapValue); |   196       __ movq(kScratchRegister, kSlotsZapValue); | 
|   197       Label loop; |   197       Label loop; | 
|   198       __ bind(&loop); |   198       __ bind(&loop); | 
|   199       __ movq(MemOperand(rsp, rax, times_pointer_size, 0), |   199       __ movp(MemOperand(rsp, rax, times_pointer_size, 0), | 
|   200               kScratchRegister); |   200               kScratchRegister); | 
|   201       __ decl(rax); |   201       __ decl(rax); | 
|   202       __ j(not_zero, &loop); |   202       __ j(not_zero, &loop); | 
|   203       __ pop(rax); |   203       __ pop(rax); | 
|   204     } else { |   204     } else { | 
|   205       __ subq(rsp, Immediate(slots * kPointerSize)); |   205       __ subq(rsp, Immediate(slots * kPointerSize)); | 
|   206 #ifdef _MSC_VER |   206 #ifdef _MSC_VER | 
|   207       MakeSureStackPagesMapped(slots * kPointerSize); |   207       MakeSureStackPagesMapped(slots * kPointerSize); | 
|   208 #endif |   208 #endif | 
|   209     } |   209     } | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   221     __ push(rdi); |   221     __ push(rdi); | 
|   222     if (heap_slots <= FastNewContextStub::kMaximumSlots) { |   222     if (heap_slots <= FastNewContextStub::kMaximumSlots) { | 
|   223       FastNewContextStub stub(heap_slots); |   223       FastNewContextStub stub(heap_slots); | 
|   224       __ CallStub(&stub); |   224       __ CallStub(&stub); | 
|   225     } else { |   225     } else { | 
|   226       __ CallRuntime(Runtime::kNewFunctionContext, 1); |   226       __ CallRuntime(Runtime::kNewFunctionContext, 1); | 
|   227     } |   227     } | 
|   228     RecordSafepoint(Safepoint::kNoLazyDeopt); |   228     RecordSafepoint(Safepoint::kNoLazyDeopt); | 
|   229     // Context is returned in both rax and rsi.  It replaces the context |   229     // Context is returned in both rax and rsi.  It replaces the context | 
|   230     // passed to us.  It's saved in the stack and kept live in rsi. |   230     // passed to us.  It's saved in the stack and kept live in rsi. | 
|   231     __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); |   231     __ movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); | 
|   232  |   232  | 
|   233     // Copy any necessary parameters into the context. |   233     // Copy any necessary parameters into the context. | 
|   234     int num_parameters = scope()->num_parameters(); |   234     int num_parameters = scope()->num_parameters(); | 
|   235     for (int i = 0; i < num_parameters; i++) { |   235     for (int i = 0; i < num_parameters; i++) { | 
|   236       Variable* var = scope()->parameter(i); |   236       Variable* var = scope()->parameter(i); | 
|   237       if (var->IsContextSlot()) { |   237       if (var->IsContextSlot()) { | 
|   238         int parameter_offset = StandardFrameConstants::kCallerSPOffset + |   238         int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 
|   239             (num_parameters - 1 - i) * kPointerSize; |   239             (num_parameters - 1 - i) * kPointerSize; | 
|   240         // Load parameter from stack. |   240         // Load parameter from stack. | 
|   241         __ movq(rax, Operand(rbp, parameter_offset)); |   241         __ movp(rax, Operand(rbp, parameter_offset)); | 
|   242         // Store it in the context. |   242         // Store it in the context. | 
|   243         int context_offset = Context::SlotOffset(var->index()); |   243         int context_offset = Context::SlotOffset(var->index()); | 
|   244         __ movq(Operand(rsi, context_offset), rax); |   244         __ movp(Operand(rsi, context_offset), rax); | 
|   245         // Update the write barrier. This clobbers rax and rbx. |   245         // Update the write barrier. This clobbers rax and rbx. | 
|   246         __ RecordWriteContextSlot(rsi, context_offset, rax, rbx, kSaveFPRegs); |   246         __ RecordWriteContextSlot(rsi, context_offset, rax, rbx, kSaveFPRegs); | 
|   247       } |   247       } | 
|   248     } |   248     } | 
|   249     Comment(";;; End allocate local context"); |   249     Comment(";;; End allocate local context"); | 
|   250   } |   250   } | 
|   251  |   251  | 
|   252   // Trace the call. |   252   // Trace the call. | 
|   253   if (FLAG_trace && info()->IsOptimizing()) { |   253   if (FLAG_trace && info()->IsOptimizing()) { | 
|   254     __ CallRuntime(Runtime::kTraceEnter, 0); |   254     __ CallRuntime(Runtime::kTraceEnter, 0); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   287     } else { |   287     } else { | 
|   288       Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); |   288       Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); | 
|   289     } |   289     } | 
|   290     if (jump_table_[i].needs_frame) { |   290     if (jump_table_[i].needs_frame) { | 
|   291       ASSERT(!info()->saves_caller_doubles()); |   291       ASSERT(!info()->saves_caller_doubles()); | 
|   292       __ Move(kScratchRegister, ExternalReference::ForDeoptEntry(entry)); |   292       __ Move(kScratchRegister, ExternalReference::ForDeoptEntry(entry)); | 
|   293       if (needs_frame.is_bound()) { |   293       if (needs_frame.is_bound()) { | 
|   294         __ jmp(&needs_frame); |   294         __ jmp(&needs_frame); | 
|   295       } else { |   295       } else { | 
|   296         __ bind(&needs_frame); |   296         __ bind(&needs_frame); | 
|   297         __ movq(rsi, MemOperand(rbp, StandardFrameConstants::kContextOffset)); |   297         __ movp(rsi, MemOperand(rbp, StandardFrameConstants::kContextOffset)); | 
|   298         __ push(rbp); |   298         __ push(rbp); | 
|   299         __ movq(rbp, rsp); |   299         __ movp(rbp, rsp); | 
|   300         __ push(rsi); |   300         __ push(rsi); | 
|   301         // This variant of deopt can only be used with stubs. Since we don't |   301         // This variant of deopt can only be used with stubs. Since we don't | 
|   302         // have a function pointer to install in the stack frame that we're |   302         // have a function pointer to install in the stack frame that we're | 
|   303         // building, install a special marker there instead. |   303         // building, install a special marker there instead. | 
|   304         ASSERT(info()->IsStub()); |   304         ASSERT(info()->IsStub()); | 
|   305         __ Move(rsi, Smi::FromInt(StackFrame::STUB)); |   305         __ Move(rsi, Smi::FromInt(StackFrame::STUB)); | 
|   306         __ push(rsi); |   306         __ push(rsi); | 
|   307         __ movq(rsi, MemOperand(rsp, kPointerSize)); |   307         __ movp(rsi, MemOperand(rsp, kPointerSize)); | 
|   308         __ call(kScratchRegister); |   308         __ call(kScratchRegister); | 
|   309       } |   309       } | 
|   310     } else { |   310     } else { | 
|   311       if (info()->saves_caller_doubles()) { |   311       if (info()->saves_caller_doubles()) { | 
|   312         ASSERT(info()->IsStub()); |   312         ASSERT(info()->IsStub()); | 
|   313         RestoreCallerDoubles(); |   313         RestoreCallerDoubles(); | 
|   314       } |   314       } | 
|   315       __ call(entry, RelocInfo::RUNTIME_ENTRY); |   315       __ call(entry, RelocInfo::RUNTIME_ENTRY); | 
|   316     } |   316     } | 
|   317   } |   317   } | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|   346         __ Push(Smi::FromInt(StackFrame::STUB)); |   346         __ Push(Smi::FromInt(StackFrame::STUB)); | 
|   347         __ lea(rbp, Operand(rsp, 2 * kPointerSize)); |   347         __ lea(rbp, Operand(rsp, 2 * kPointerSize)); | 
|   348         Comment(";;; Deferred code"); |   348         Comment(";;; Deferred code"); | 
|   349       } |   349       } | 
|   350       code->Generate(); |   350       code->Generate(); | 
|   351       if (NeedsDeferredFrame()) { |   351       if (NeedsDeferredFrame()) { | 
|   352         __ bind(code->done()); |   352         __ bind(code->done()); | 
|   353         Comment(";;; Destroy frame"); |   353         Comment(";;; Destroy frame"); | 
|   354         ASSERT(frame_is_built_); |   354         ASSERT(frame_is_built_); | 
|   355         frame_is_built_ = false; |   355         frame_is_built_ = false; | 
|   356         __ movq(rsp, rbp); |   356         __ movp(rsp, rbp); | 
|   357         __ pop(rbp); |   357         __ pop(rbp); | 
|   358       } |   358       } | 
|   359       __ jmp(code->exit()); |   359       __ jmp(code->exit()); | 
|   360     } |   360     } | 
|   361   } |   361   } | 
|   362  |   362  | 
|   363   // Deferred code is the last part of the instruction sequence. Mark |   363   // Deferred code is the last part of the instruction sequence. Mark | 
|   364   // the generated code as done unless we bailed out. |   364   // the generated code as done unless we bailed out. | 
|   365   if (!is_aborted()) status_ = DONE; |   365   if (!is_aborted()) status_ = DONE; | 
|   366   return !is_aborted(); |   366   return !is_aborted(); | 
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   629  |   629  | 
|   630   __ CallRuntime(function, num_arguments, save_doubles); |   630   __ CallRuntime(function, num_arguments, save_doubles); | 
|   631  |   631  | 
|   632   RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); |   632   RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); | 
|   633 } |   633 } | 
|   634  |   634  | 
|   635  |   635  | 
|   636 void LCodeGen::LoadContextFromDeferred(LOperand* context) { |   636 void LCodeGen::LoadContextFromDeferred(LOperand* context) { | 
|   637   if (context->IsRegister()) { |   637   if (context->IsRegister()) { | 
|   638     if (!ToRegister(context).is(rsi)) { |   638     if (!ToRegister(context).is(rsi)) { | 
|   639       __ movq(rsi, ToRegister(context)); |   639       __ movp(rsi, ToRegister(context)); | 
|   640     } |   640     } | 
|   641   } else if (context->IsStackSlot()) { |   641   } else if (context->IsStackSlot()) { | 
|   642     __ movq(rsi, ToOperand(context)); |   642     __ movp(rsi, ToOperand(context)); | 
|   643   } else if (context->IsConstantOperand()) { |   643   } else if (context->IsConstantOperand()) { | 
|   644     HConstant* constant = |   644     HConstant* constant = | 
|   645         chunk_->LookupConstant(LConstantOperand::cast(context)); |   645         chunk_->LookupConstant(LConstantOperand::cast(context)); | 
|   646     __ Move(rsi, Handle<Object>::cast(constant->handle(isolate()))); |   646     __ Move(rsi, Handle<Object>::cast(constant->handle(isolate()))); | 
|   647   } else { |   647   } else { | 
|   648     UNREACHABLE(); |   648     UNREACHABLE(); | 
|   649   } |   649   } | 
|   650 } |   650 } | 
|   651  |   651  | 
|   652  |   652  | 
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1261   } |  1261   } | 
|  1262 } |  1262 } | 
|  1263  |  1263  | 
|  1264  |  1264  | 
|  1265 void LCodeGen::DoMulI(LMulI* instr) { |  1265 void LCodeGen::DoMulI(LMulI* instr) { | 
|  1266   Register left = ToRegister(instr->left()); |  1266   Register left = ToRegister(instr->left()); | 
|  1267   LOperand* right = instr->right(); |  1267   LOperand* right = instr->right(); | 
|  1268  |  1268  | 
|  1269   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |  1269   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
|  1270     if (instr->hydrogen_value()->representation().IsSmi()) { |  1270     if (instr->hydrogen_value()->representation().IsSmi()) { | 
|  1271       __ movq(kScratchRegister, left); |  1271       __ movp(kScratchRegister, left); | 
|  1272     } else { |  1272     } else { | 
|  1273       __ movl(kScratchRegister, left); |  1273       __ movl(kScratchRegister, left); | 
|  1274     } |  1274     } | 
|  1275   } |  1275   } | 
|  1276  |  1276  | 
|  1277   bool can_overflow = |  1277   bool can_overflow = | 
|  1278       instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |  1278       instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 
|  1279   if (right->IsConstantOperand()) { |  1279   if (right->IsConstantOperand()) { | 
|  1280     int32_t right_value = ToInteger32(LConstantOperand::cast(right)); |  1280     int32_t right_value = ToInteger32(LConstantOperand::cast(right)); | 
|  1281     if (right_value == -1) { |  1281     if (right_value == -1) { | 
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1576   Register map = ToRegister(instr->value()); |  1576   Register map = ToRegister(instr->value()); | 
|  1577   __ EnumLength(result, map); |  1577   __ EnumLength(result, map); | 
|  1578 } |  1578 } | 
|  1579  |  1579  | 
|  1580  |  1580  | 
|  1581 void LCodeGen::DoElementsKind(LElementsKind* instr) { |  1581 void LCodeGen::DoElementsKind(LElementsKind* instr) { | 
|  1582   Register result = ToRegister(instr->result()); |  1582   Register result = ToRegister(instr->result()); | 
|  1583   Register input = ToRegister(instr->value()); |  1583   Register input = ToRegister(instr->value()); | 
|  1584  |  1584  | 
|  1585   // Load map into |result|. |  1585   // Load map into |result|. | 
|  1586   __ movq(result, FieldOperand(input, HeapObject::kMapOffset)); |  1586   __ movp(result, FieldOperand(input, HeapObject::kMapOffset)); | 
|  1587   // Load the map's "bit field 2" into |result|. We only need the first byte. |  1587   // Load the map's "bit field 2" into |result|. We only need the first byte. | 
|  1588   __ movzxbq(result, FieldOperand(result, Map::kBitField2Offset)); |  1588   __ movzxbq(result, FieldOperand(result, Map::kBitField2Offset)); | 
|  1589   // Retrieve elements_kind from bit field 2. |  1589   // Retrieve elements_kind from bit field 2. | 
|  1590   __ and_(result, Immediate(Map::kElementsKindMask)); |  1590   __ and_(result, Immediate(Map::kElementsKindMask)); | 
|  1591   __ shr(result, Immediate(Map::kElementsKindShift)); |  1591   __ shr(result, Immediate(Map::kElementsKindShift)); | 
|  1592 } |  1592 } | 
|  1593  |  1593  | 
|  1594  |  1594  | 
|  1595 void LCodeGen::DoValueOf(LValueOf* instr) { |  1595 void LCodeGen::DoValueOf(LValueOf* instr) { | 
|  1596   Register input = ToRegister(instr->value()); |  1596   Register input = ToRegister(instr->value()); | 
|  1597   Register result = ToRegister(instr->result()); |  1597   Register result = ToRegister(instr->result()); | 
|  1598   ASSERT(input.is(result)); |  1598   ASSERT(input.is(result)); | 
|  1599   Label done; |  1599   Label done; | 
|  1600  |  1600  | 
|  1601   if (!instr->hydrogen()->value()->IsHeapObject()) { |  1601   if (!instr->hydrogen()->value()->IsHeapObject()) { | 
|  1602     // If the object is a smi return the object. |  1602     // If the object is a smi return the object. | 
|  1603     __ JumpIfSmi(input, &done, Label::kNear); |  1603     __ JumpIfSmi(input, &done, Label::kNear); | 
|  1604   } |  1604   } | 
|  1605  |  1605  | 
|  1606   // If the object is not a value type, return the object. |  1606   // If the object is not a value type, return the object. | 
|  1607   __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister); |  1607   __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister); | 
|  1608   __ j(not_equal, &done, Label::kNear); |  1608   __ j(not_equal, &done, Label::kNear); | 
|  1609   __ movq(result, FieldOperand(input, JSValue::kValueOffset)); |  1609   __ movp(result, FieldOperand(input, JSValue::kValueOffset)); | 
|  1610  |  1610  | 
|  1611   __ bind(&done); |  1611   __ bind(&done); | 
|  1612 } |  1612 } | 
|  1613  |  1613  | 
|  1614  |  1614  | 
|  1615 void LCodeGen::DoDateField(LDateField* instr) { |  1615 void LCodeGen::DoDateField(LDateField* instr) { | 
|  1616   Register object = ToRegister(instr->date()); |  1616   Register object = ToRegister(instr->date()); | 
|  1617   Register result = ToRegister(instr->result()); |  1617   Register result = ToRegister(instr->result()); | 
|  1618   Smi* index = instr->index(); |  1618   Smi* index = instr->index(); | 
|  1619   Label runtime, done, not_date_object; |  1619   Label runtime, done, not_date_object; | 
|  1620   ASSERT(object.is(result)); |  1620   ASSERT(object.is(result)); | 
|  1621   ASSERT(object.is(rax)); |  1621   ASSERT(object.is(rax)); | 
|  1622  |  1622  | 
|  1623   Condition cc = masm()->CheckSmi(object); |  1623   Condition cc = masm()->CheckSmi(object); | 
|  1624   DeoptimizeIf(cc, instr->environment()); |  1624   DeoptimizeIf(cc, instr->environment()); | 
|  1625   __ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister); |  1625   __ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister); | 
|  1626   DeoptimizeIf(not_equal, instr->environment()); |  1626   DeoptimizeIf(not_equal, instr->environment()); | 
|  1627  |  1627  | 
|  1628   if (index->value() == 0) { |  1628   if (index->value() == 0) { | 
|  1629     __ movq(result, FieldOperand(object, JSDate::kValueOffset)); |  1629     __ movp(result, FieldOperand(object, JSDate::kValueOffset)); | 
|  1630   } else { |  1630   } else { | 
|  1631     if (index->value() < JSDate::kFirstUncachedField) { |  1631     if (index->value() < JSDate::kFirstUncachedField) { | 
|  1632       ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); |  1632       ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); | 
|  1633       Operand stamp_operand = __ ExternalOperand(stamp); |  1633       Operand stamp_operand = __ ExternalOperand(stamp); | 
|  1634       __ movq(kScratchRegister, stamp_operand); |  1634       __ movp(kScratchRegister, stamp_operand); | 
|  1635       __ cmpq(kScratchRegister, FieldOperand(object, |  1635       __ cmpq(kScratchRegister, FieldOperand(object, | 
|  1636                                              JSDate::kCacheStampOffset)); |  1636                                              JSDate::kCacheStampOffset)); | 
|  1637       __ j(not_equal, &runtime, Label::kNear); |  1637       __ j(not_equal, &runtime, Label::kNear); | 
|  1638       __ movq(result, FieldOperand(object, JSDate::kValueOffset + |  1638       __ movp(result, FieldOperand(object, JSDate::kValueOffset + | 
|  1639                                            kPointerSize * index->value())); |  1639                                            kPointerSize * index->value())); | 
|  1640       __ jmp(&done, Label::kNear); |  1640       __ jmp(&done, Label::kNear); | 
|  1641     } |  1641     } | 
|  1642     __ bind(&runtime); |  1642     __ bind(&runtime); | 
|  1643     __ PrepareCallCFunction(2); |  1643     __ PrepareCallCFunction(2); | 
|  1644     __ movq(arg_reg_1, object); |  1644     __ movp(arg_reg_1, object); | 
|  1645     __ Move(arg_reg_2, index, RelocInfo::NONE64); |  1645     __ Move(arg_reg_2, index, RelocInfo::NONE64); | 
|  1646     __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); |  1646     __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); | 
|  1647     __ bind(&done); |  1647     __ bind(&done); | 
|  1648   } |  1648   } | 
|  1649 } |  1649 } | 
|  1650  |  1650  | 
|  1651  |  1651  | 
|  1652 Operand LCodeGen::BuildSeqStringOperand(Register string, |  1652 Operand LCodeGen::BuildSeqStringOperand(Register string, | 
|  1653                                         LOperand* index, |  1653                                         LOperand* index, | 
|  1654                                         String::Encoding encoding) { |  1654                                         String::Encoding encoding) { | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  1667 } |  1667 } | 
|  1668  |  1668  | 
|  1669  |  1669  | 
|  1670 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) { |  1670 void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) { | 
|  1671   String::Encoding encoding = instr->hydrogen()->encoding(); |  1671   String::Encoding encoding = instr->hydrogen()->encoding(); | 
|  1672   Register result = ToRegister(instr->result()); |  1672   Register result = ToRegister(instr->result()); | 
|  1673   Register string = ToRegister(instr->string()); |  1673   Register string = ToRegister(instr->string()); | 
|  1674  |  1674  | 
|  1675   if (FLAG_debug_code) { |  1675   if (FLAG_debug_code) { | 
|  1676     __ push(string); |  1676     __ push(string); | 
|  1677     __ movq(string, FieldOperand(string, HeapObject::kMapOffset)); |  1677     __ movp(string, FieldOperand(string, HeapObject::kMapOffset)); | 
|  1678     __ movzxbq(string, FieldOperand(string, Map::kInstanceTypeOffset)); |  1678     __ movzxbq(string, FieldOperand(string, Map::kInstanceTypeOffset)); | 
|  1679  |  1679  | 
|  1680     __ andb(string, Immediate(kStringRepresentationMask | kStringEncodingMask)); |  1680     __ andb(string, Immediate(kStringRepresentationMask | kStringEncodingMask)); | 
|  1681     static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |  1681     static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 
|  1682     static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |  1682     static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 
|  1683     __ cmpq(string, Immediate(encoding == String::ONE_BYTE_ENCODING |  1683     __ cmpq(string, Immediate(encoding == String::ONE_BYTE_ENCODING | 
|  1684                               ? one_byte_seq_type : two_byte_seq_type)); |  1684                               ? one_byte_seq_type : two_byte_seq_type)); | 
|  1685     __ Check(equal, kUnexpectedStringType); |  1685     __ Check(equal, kUnexpectedStringType); | 
|  1686     __ pop(string); |  1686     __ pop(string); | 
|  1687   } |  1687   } | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1808     Condition condition = (operation == HMathMinMax::kMathMin) |  1808     Condition condition = (operation == HMathMinMax::kMathMin) | 
|  1809         ? less_equal |  1809         ? less_equal | 
|  1810         : greater_equal; |  1810         : greater_equal; | 
|  1811     Register left_reg = ToRegister(left); |  1811     Register left_reg = ToRegister(left); | 
|  1812     if (right->IsConstantOperand()) { |  1812     if (right->IsConstantOperand()) { | 
|  1813       Immediate right_imm = |  1813       Immediate right_imm = | 
|  1814           Immediate(ToInteger32(LConstantOperand::cast(right))); |  1814           Immediate(ToInteger32(LConstantOperand::cast(right))); | 
|  1815       ASSERT(!instr->hydrogen_value()->representation().IsSmi()); |  1815       ASSERT(!instr->hydrogen_value()->representation().IsSmi()); | 
|  1816       __ cmpl(left_reg, right_imm); |  1816       __ cmpl(left_reg, right_imm); | 
|  1817       __ j(condition, &return_left, Label::kNear); |  1817       __ j(condition, &return_left, Label::kNear); | 
|  1818       __ movq(left_reg, right_imm); |  1818       __ movp(left_reg, right_imm); | 
|  1819     } else if (right->IsRegister()) { |  1819     } else if (right->IsRegister()) { | 
|  1820       Register right_reg = ToRegister(right); |  1820       Register right_reg = ToRegister(right); | 
|  1821       if (instr->hydrogen_value()->representation().IsSmi()) { |  1821       if (instr->hydrogen_value()->representation().IsSmi()) { | 
|  1822         __ cmpq(left_reg, right_reg); |  1822         __ cmpq(left_reg, right_reg); | 
|  1823       } else { |  1823       } else { | 
|  1824         __ cmpl(left_reg, right_reg); |  1824         __ cmpl(left_reg, right_reg); | 
|  1825       } |  1825       } | 
|  1826       __ j(condition, &return_left, Label::kNear); |  1826       __ j(condition, &return_left, Label::kNear); | 
|  1827       __ movq(left_reg, right_reg); |  1827       __ movp(left_reg, right_reg); | 
|  1828     } else { |  1828     } else { | 
|  1829       Operand right_op = ToOperand(right); |  1829       Operand right_op = ToOperand(right); | 
|  1830       if (instr->hydrogen_value()->representation().IsSmi()) { |  1830       if (instr->hydrogen_value()->representation().IsSmi()) { | 
|  1831         __ cmpq(left_reg, right_op); |  1831         __ cmpq(left_reg, right_op); | 
|  1832       } else { |  1832       } else { | 
|  1833         __ cmpl(left_reg, right_op); |  1833         __ cmpl(left_reg, right_op); | 
|  1834       } |  1834       } | 
|  1835       __ j(condition, &return_left, Label::kNear); |  1835       __ j(condition, &return_left, Label::kNear); | 
|  1836       __ movq(left_reg, right_op); |  1836       __ movp(left_reg, right_op); | 
|  1837     } |  1837     } | 
|  1838     __ bind(&return_left); |  1838     __ bind(&return_left); | 
|  1839   } else { |  1839   } else { | 
|  1840     ASSERT(instr->hydrogen()->representation().IsDouble()); |  1840     ASSERT(instr->hydrogen()->representation().IsDouble()); | 
|  1841     Label check_nan_left, check_zero, return_left, return_right; |  1841     Label check_nan_left, check_zero, return_left, return_right; | 
|  1842     Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; |  1842     Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; | 
|  1843     XMMRegister left_reg = ToDoubleRegister(left); |  1843     XMMRegister left_reg = ToDoubleRegister(left); | 
|  1844     XMMRegister right_reg = ToDoubleRegister(right); |  1844     XMMRegister right_reg = ToDoubleRegister(right); | 
|  1845     __ ucomisd(left_reg, right_reg); |  1845     __ ucomisd(left_reg, right_reg); | 
|  1846     __ j(parity_even, &check_nan_left, Label::kNear);  // At least one NaN. |  1846     __ j(parity_even, &check_nan_left, Label::kNear);  // At least one NaN. | 
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2032         __ j(equal, instr->FalseLabel(chunk_)); |  2032         __ j(equal, instr->FalseLabel(chunk_)); | 
|  2033         __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); |  2033         __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | 
|  2034       } else if (expected.NeedsMap()) { |  2034       } else if (expected.NeedsMap()) { | 
|  2035         // If we need a map later and have a Smi -> deopt. |  2035         // If we need a map later and have a Smi -> deopt. | 
|  2036         __ testb(reg, Immediate(kSmiTagMask)); |  2036         __ testb(reg, Immediate(kSmiTagMask)); | 
|  2037         DeoptimizeIf(zero, instr->environment()); |  2037         DeoptimizeIf(zero, instr->environment()); | 
|  2038       } |  2038       } | 
|  2039  |  2039  | 
|  2040       const Register map = kScratchRegister; |  2040       const Register map = kScratchRegister; | 
|  2041       if (expected.NeedsMap()) { |  2041       if (expected.NeedsMap()) { | 
|  2042         __ movq(map, FieldOperand(reg, HeapObject::kMapOffset)); |  2042         __ movp(map, FieldOperand(reg, HeapObject::kMapOffset)); | 
|  2043  |  2043  | 
|  2044         if (expected.CanBeUndetectable()) { |  2044         if (expected.CanBeUndetectable()) { | 
|  2045           // Undetectable -> false. |  2045           // Undetectable -> false. | 
|  2046           __ testb(FieldOperand(map, Map::kBitFieldOffset), |  2046           __ testb(FieldOperand(map, Map::kBitFieldOffset), | 
|  2047                    Immediate(1 << Map::kIsUndetectable)); |  2047                    Immediate(1 << Map::kIsUndetectable)); | 
|  2048           __ j(not_zero, instr->FalseLabel(chunk_)); |  2048           __ j(not_zero, instr->FalseLabel(chunk_)); | 
|  2049         } |  2049         } | 
|  2050       } |  2050       } | 
|  2051  |  2051  | 
|  2052       if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { |  2052       if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2266 Condition LCodeGen::EmitIsObject(Register input, |  2266 Condition LCodeGen::EmitIsObject(Register input, | 
|  2267                                  Label* is_not_object, |  2267                                  Label* is_not_object, | 
|  2268                                  Label* is_object) { |  2268                                  Label* is_object) { | 
|  2269   ASSERT(!input.is(kScratchRegister)); |  2269   ASSERT(!input.is(kScratchRegister)); | 
|  2270  |  2270  | 
|  2271   __ JumpIfSmi(input, is_not_object); |  2271   __ JumpIfSmi(input, is_not_object); | 
|  2272  |  2272  | 
|  2273   __ CompareRoot(input, Heap::kNullValueRootIndex); |  2273   __ CompareRoot(input, Heap::kNullValueRootIndex); | 
|  2274   __ j(equal, is_object); |  2274   __ j(equal, is_object); | 
|  2275  |  2275  | 
|  2276   __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); |  2276   __ movp(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); | 
|  2277   // Undetectable objects behave like undefined. |  2277   // Undetectable objects behave like undefined. | 
|  2278   __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset), |  2278   __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset), | 
|  2279            Immediate(1 << Map::kIsUndetectable)); |  2279            Immediate(1 << Map::kIsUndetectable)); | 
|  2280   __ j(not_zero, is_not_object); |  2280   __ j(not_zero, is_not_object); | 
|  2281  |  2281  | 
|  2282   __ movzxbl(kScratchRegister, |  2282   __ movzxbl(kScratchRegister, | 
|  2283              FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); |  2283              FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); | 
|  2284   __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |  2284   __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 
|  2285   __ j(below, is_not_object); |  2285   __ j(below, is_not_object); | 
|  2286   __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); |  2286   __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2340 } |  2340 } | 
|  2341  |  2341  | 
|  2342  |  2342  | 
|  2343 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { |  2343 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { | 
|  2344   Register input = ToRegister(instr->value()); |  2344   Register input = ToRegister(instr->value()); | 
|  2345   Register temp = ToRegister(instr->temp()); |  2345   Register temp = ToRegister(instr->temp()); | 
|  2346  |  2346  | 
|  2347   if (!instr->hydrogen()->value()->IsHeapObject()) { |  2347   if (!instr->hydrogen()->value()->IsHeapObject()) { | 
|  2348     __ JumpIfSmi(input, instr->FalseLabel(chunk_)); |  2348     __ JumpIfSmi(input, instr->FalseLabel(chunk_)); | 
|  2349   } |  2349   } | 
|  2350   __ movq(temp, FieldOperand(input, HeapObject::kMapOffset)); |  2350   __ movp(temp, FieldOperand(input, HeapObject::kMapOffset)); | 
|  2351   __ testb(FieldOperand(temp, Map::kBitFieldOffset), |  2351   __ testb(FieldOperand(temp, Map::kBitFieldOffset), | 
|  2352            Immediate(1 << Map::kIsUndetectable)); |  2352            Immediate(1 << Map::kIsUndetectable)); | 
|  2353   EmitBranch(instr, not_zero); |  2353   EmitBranch(instr, not_zero); | 
|  2354 } |  2354 } | 
|  2355  |  2355  | 
|  2356  |  2356  | 
|  2357 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { |  2357 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { | 
|  2358   ASSERT(ToRegister(instr->context()).is(rsi)); |  2358   ASSERT(ToRegister(instr->context()).is(rsi)); | 
|  2359   Token::Value op = instr->op(); |  2359   Token::Value op = instr->op(); | 
|  2360  |  2360  | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2446                   LAST_SPEC_OBJECT_TYPE - 1); |  2446                   LAST_SPEC_OBJECT_TYPE - 1); | 
|  2447     STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); |  2447     STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 
|  2448     __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp); |  2448     __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp); | 
|  2449     __ j(below, is_false); |  2449     __ j(below, is_false); | 
|  2450     __ j(equal, is_true); |  2450     __ j(equal, is_true); | 
|  2451     __ CmpInstanceType(temp, LAST_SPEC_OBJECT_TYPE); |  2451     __ CmpInstanceType(temp, LAST_SPEC_OBJECT_TYPE); | 
|  2452     __ j(equal, is_true); |  2452     __ j(equal, is_true); | 
|  2453   } else { |  2453   } else { | 
|  2454     // Faster code path to avoid two compares: subtract lower bound from the |  2454     // Faster code path to avoid two compares: subtract lower bound from the | 
|  2455     // actual type and do a signed compare with the width of the type range. |  2455     // actual type and do a signed compare with the width of the type range. | 
|  2456     __ movq(temp, FieldOperand(input, HeapObject::kMapOffset)); |  2456     __ movp(temp, FieldOperand(input, HeapObject::kMapOffset)); | 
|  2457     __ movzxbl(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); |  2457     __ movzxbl(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); | 
|  2458     __ subq(temp2, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |  2458     __ subq(temp2, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 
|  2459     __ cmpq(temp2, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - |  2459     __ cmpq(temp2, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - | 
|  2460                              FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |  2460                              FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 
|  2461     __ j(above, is_false); |  2461     __ j(above, is_false); | 
|  2462   } |  2462   } | 
|  2463  |  2463  | 
|  2464   // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. |  2464   // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. | 
|  2465   // Check if the constructor in the map is a function. |  2465   // Check if the constructor in the map is a function. | 
|  2466   __ movq(temp, FieldOperand(temp, Map::kConstructorOffset)); |  2466   __ movp(temp, FieldOperand(temp, Map::kConstructorOffset)); | 
|  2467  |  2467  | 
|  2468   // Objects with a non-function constructor have class 'Object'. |  2468   // Objects with a non-function constructor have class 'Object'. | 
|  2469   __ CmpObjectType(temp, JS_FUNCTION_TYPE, kScratchRegister); |  2469   __ CmpObjectType(temp, JS_FUNCTION_TYPE, kScratchRegister); | 
|  2470   if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) { |  2470   if (class_name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("Object"))) { | 
|  2471     __ j(not_equal, is_true); |  2471     __ j(not_equal, is_true); | 
|  2472   } else { |  2472   } else { | 
|  2473     __ j(not_equal, is_false); |  2473     __ j(not_equal, is_false); | 
|  2474   } |  2474   } | 
|  2475  |  2475  | 
|  2476   // temp now contains the constructor function. Grab the |  2476   // temp now contains the constructor function. Grab the | 
|  2477   // instance class name from there. |  2477   // instance class name from there. | 
|  2478   __ movq(temp, FieldOperand(temp, JSFunction::kSharedFunctionInfoOffset)); |  2478   __ movp(temp, FieldOperand(temp, JSFunction::kSharedFunctionInfoOffset)); | 
|  2479   __ movq(temp, FieldOperand(temp, |  2479   __ movp(temp, FieldOperand(temp, | 
|  2480                              SharedFunctionInfo::kInstanceClassNameOffset)); |  2480                              SharedFunctionInfo::kInstanceClassNameOffset)); | 
|  2481   // The class name we are testing against is internalized since it's a literal. |  2481   // The class name we are testing against is internalized since it's a literal. | 
|  2482   // The name in the constructor is internalized because of the way the context |  2482   // The name in the constructor is internalized because of the way the context | 
|  2483   // is booted.  This routine isn't expected to work for random API-created |  2483   // is booted.  This routine isn't expected to work for random API-created | 
|  2484   // classes and it doesn't have to because you can't access it with natives |  2484   // classes and it doesn't have to because you can't access it with natives | 
|  2485   // syntax.  Since both sides are internalized it is sufficient to use an |  2485   // syntax.  Since both sides are internalized it is sufficient to use an | 
|  2486   // identity comparison. |  2486   // identity comparison. | 
|  2487   ASSERT(class_name->IsInternalizedString()); |  2487   ASSERT(class_name->IsInternalizedString()); | 
|  2488   __ Cmp(temp, class_name); |  2488   __ Cmp(temp, class_name); | 
|  2489   // End with the answer in the z flag. |  2489   // End with the answer in the z flag. | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2553  |  2553  | 
|  2554   // A Smi is not an instance of anything. |  2554   // A Smi is not an instance of anything. | 
|  2555   __ JumpIfSmi(object, &false_result, Label::kNear); |  2555   __ JumpIfSmi(object, &false_result, Label::kNear); | 
|  2556  |  2556  | 
|  2557   // This is the inlined call site instanceof cache. The two occurences of the |  2557   // This is the inlined call site instanceof cache. The two occurences of the | 
|  2558   // hole value will be patched to the last map/result pair generated by the |  2558   // hole value will be patched to the last map/result pair generated by the | 
|  2559   // instanceof stub. |  2559   // instanceof stub. | 
|  2560   Label cache_miss; |  2560   Label cache_miss; | 
|  2561   // Use a temp register to avoid memory operands with variable lengths. |  2561   // Use a temp register to avoid memory operands with variable lengths. | 
|  2562   Register map = ToRegister(instr->temp()); |  2562   Register map = ToRegister(instr->temp()); | 
|  2563   __ movq(map, FieldOperand(object, HeapObject::kMapOffset)); |  2563   __ movp(map, FieldOperand(object, HeapObject::kMapOffset)); | 
|  2564   __ bind(deferred->map_check());  // Label for calculating code patching. |  2564   __ bind(deferred->map_check());  // Label for calculating code patching. | 
|  2565   Handle<Cell> cache_cell = factory()->NewCell(factory()->the_hole_value()); |  2565   Handle<Cell> cache_cell = factory()->NewCell(factory()->the_hole_value()); | 
|  2566   __ Move(kScratchRegister, cache_cell, RelocInfo::CELL); |  2566   __ Move(kScratchRegister, cache_cell, RelocInfo::CELL); | 
|  2567   __ cmpq(map, Operand(kScratchRegister, 0)); |  2567   __ cmpq(map, Operand(kScratchRegister, 0)); | 
|  2568   __ j(not_equal, &cache_miss, Label::kNear); |  2568   __ j(not_equal, &cache_miss, Label::kNear); | 
|  2569   // Patched to load either true or false. |  2569   // Patched to load either true or false. | 
|  2570   __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); |  2570   __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); | 
|  2571 #ifdef DEBUG |  2571 #ifdef DEBUG | 
|  2572   // Check that the code size between patch label and patch sites is invariant. |  2572   // Check that the code size between patch label and patch sites is invariant. | 
|  2573   Label end_of_patched_code; |  2573   Label end_of_patched_code; | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2617     CallCodeGeneric(stub.GetCode(isolate()), |  2617     CallCodeGeneric(stub.GetCode(isolate()), | 
|  2618                     RelocInfo::CODE_TARGET, |  2618                     RelocInfo::CODE_TARGET, | 
|  2619                     instr, |  2619                     instr, | 
|  2620                     RECORD_SAFEPOINT_WITH_REGISTERS, |  2620                     RECORD_SAFEPOINT_WITH_REGISTERS, | 
|  2621                     2); |  2621                     2); | 
|  2622     ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check)); |  2622     ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check)); | 
|  2623     LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); |  2623     LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); | 
|  2624     safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |  2624     safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 
|  2625     // Move result to a register that survives the end of the |  2625     // Move result to a register that survives the end of the | 
|  2626     // PushSafepointRegisterScope. |  2626     // PushSafepointRegisterScope. | 
|  2627     __ movq(kScratchRegister, rax); |  2627     __ movp(kScratchRegister, rax); | 
|  2628   } |  2628   } | 
|  2629   __ testq(kScratchRegister, kScratchRegister); |  2629   __ testq(kScratchRegister, kScratchRegister); | 
|  2630   Label load_false; |  2630   Label load_false; | 
|  2631   Label done; |  2631   Label done; | 
|  2632   __ j(not_zero, &load_false, Label::kNear); |  2632   __ j(not_zero, &load_false, Label::kNear); | 
|  2633   __ LoadRoot(rax, Heap::kTrueValueRootIndex); |  2633   __ LoadRoot(rax, Heap::kTrueValueRootIndex); | 
|  2634   __ jmp(&done, Label::kNear); |  2634   __ jmp(&done, Label::kNear); | 
|  2635   __ bind(&load_false); |  2635   __ bind(&load_false); | 
|  2636   __ LoadRoot(rax, Heap::kFalseValueRootIndex); |  2636   __ LoadRoot(rax, Heap::kFalseValueRootIndex); | 
|  2637   __ bind(&done); |  2637   __ bind(&done); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  2657 } |  2657 } | 
|  2658  |  2658  | 
|  2659  |  2659  | 
|  2660 void LCodeGen::DoReturn(LReturn* instr) { |  2660 void LCodeGen::DoReturn(LReturn* instr) { | 
|  2661   if (FLAG_trace && info()->IsOptimizing()) { |  2661   if (FLAG_trace && info()->IsOptimizing()) { | 
|  2662     // Preserve the return value on the stack and rely on the runtime call |  2662     // Preserve the return value on the stack and rely on the runtime call | 
|  2663     // to return the value in the same register.  We're leaving the code |  2663     // to return the value in the same register.  We're leaving the code | 
|  2664     // managed by the register allocator and tearing down the frame, it's |  2664     // managed by the register allocator and tearing down the frame, it's | 
|  2665     // safe to write to the context register. |  2665     // safe to write to the context register. | 
|  2666     __ push(rax); |  2666     __ push(rax); | 
|  2667     __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  2667     __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  2668     __ CallRuntime(Runtime::kTraceExit, 1); |  2668     __ CallRuntime(Runtime::kTraceExit, 1); | 
|  2669   } |  2669   } | 
|  2670   if (info()->saves_caller_doubles()) { |  2670   if (info()->saves_caller_doubles()) { | 
|  2671     RestoreCallerDoubles(); |  2671     RestoreCallerDoubles(); | 
|  2672   } |  2672   } | 
|  2673   int no_frame_start = -1; |  2673   int no_frame_start = -1; | 
|  2674   if (NeedsEagerFrame()) { |  2674   if (NeedsEagerFrame()) { | 
|  2675     __ movq(rsp, rbp); |  2675     __ movp(rsp, rbp); | 
|  2676     __ pop(rbp); |  2676     __ pop(rbp); | 
|  2677     no_frame_start = masm_->pc_offset(); |  2677     no_frame_start = masm_->pc_offset(); | 
|  2678   } |  2678   } | 
|  2679   if (instr->has_constant_parameter_count()) { |  2679   if (instr->has_constant_parameter_count()) { | 
|  2680     __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize, |  2680     __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize, | 
|  2681            rcx); |  2681            rcx); | 
|  2682   } else { |  2682   } else { | 
|  2683     Register reg = ToRegister(instr->parameter_count()); |  2683     Register reg = ToRegister(instr->parameter_count()); | 
|  2684     // The argument count parameter is a smi |  2684     // The argument count parameter is a smi | 
|  2685     __ SmiToInteger32(reg, reg); |  2685     __ SmiToInteger32(reg, reg); | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2726   // to update the property details in the property dictionary to mark |  2726   // to update the property details in the property dictionary to mark | 
|  2727   // it as no longer deleted. We deoptimize in that case. |  2727   // it as no longer deleted. We deoptimize in that case. | 
|  2728   if (instr->hydrogen()->RequiresHoleCheck()) { |  2728   if (instr->hydrogen()->RequiresHoleCheck()) { | 
|  2729     // We have a temp because CompareRoot might clobber kScratchRegister. |  2729     // We have a temp because CompareRoot might clobber kScratchRegister. | 
|  2730     Register cell = ToRegister(instr->temp()); |  2730     Register cell = ToRegister(instr->temp()); | 
|  2731     ASSERT(!value.is(cell)); |  2731     ASSERT(!value.is(cell)); | 
|  2732     __ Move(cell, cell_handle, RelocInfo::CELL); |  2732     __ Move(cell, cell_handle, RelocInfo::CELL); | 
|  2733     __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex); |  2733     __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex); | 
|  2734     DeoptimizeIf(equal, instr->environment()); |  2734     DeoptimizeIf(equal, instr->environment()); | 
|  2735     // Store the value. |  2735     // Store the value. | 
|  2736     __ movq(Operand(cell, 0), value); |  2736     __ movp(Operand(cell, 0), value); | 
|  2737   } else { |  2737   } else { | 
|  2738     // Store the value. |  2738     // Store the value. | 
|  2739     __ Move(kScratchRegister, cell_handle, RelocInfo::CELL); |  2739     __ Move(kScratchRegister, cell_handle, RelocInfo::CELL); | 
|  2740     __ movq(Operand(kScratchRegister, 0), value); |  2740     __ movp(Operand(kScratchRegister, 0), value); | 
|  2741   } |  2741   } | 
|  2742   // Cells are always rescanned, so no write barrier here. |  2742   // Cells are always rescanned, so no write barrier here. | 
|  2743 } |  2743 } | 
|  2744  |  2744  | 
|  2745  |  2745  | 
|  2746 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |  2746 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 
|  2747   Register context = ToRegister(instr->context()); |  2747   Register context = ToRegister(instr->context()); | 
|  2748   Register result = ToRegister(instr->result()); |  2748   Register result = ToRegister(instr->result()); | 
|  2749   __ movq(result, ContextOperand(context, instr->slot_index())); |  2749   __ movp(result, ContextOperand(context, instr->slot_index())); | 
|  2750   if (instr->hydrogen()->RequiresHoleCheck()) { |  2750   if (instr->hydrogen()->RequiresHoleCheck()) { | 
|  2751     __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |  2751     __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 
|  2752     if (instr->hydrogen()->DeoptimizesOnHole()) { |  2752     if (instr->hydrogen()->DeoptimizesOnHole()) { | 
|  2753       DeoptimizeIf(equal, instr->environment()); |  2753       DeoptimizeIf(equal, instr->environment()); | 
|  2754     } else { |  2754     } else { | 
|  2755       Label is_not_hole; |  2755       Label is_not_hole; | 
|  2756       __ j(not_equal, &is_not_hole, Label::kNear); |  2756       __ j(not_equal, &is_not_hole, Label::kNear); | 
|  2757       __ LoadRoot(result, Heap::kUndefinedValueRootIndex); |  2757       __ LoadRoot(result, Heap::kUndefinedValueRootIndex); | 
|  2758       __ bind(&is_not_hole); |  2758       __ bind(&is_not_hole); | 
|  2759     } |  2759     } | 
|  2760   } |  2760   } | 
|  2761 } |  2761 } | 
|  2762  |  2762  | 
|  2763  |  2763  | 
|  2764 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { |  2764 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { | 
|  2765   Register context = ToRegister(instr->context()); |  2765   Register context = ToRegister(instr->context()); | 
|  2766   Register value = ToRegister(instr->value()); |  2766   Register value = ToRegister(instr->value()); | 
|  2767  |  2767  | 
|  2768   Operand target = ContextOperand(context, instr->slot_index()); |  2768   Operand target = ContextOperand(context, instr->slot_index()); | 
|  2769  |  2769  | 
|  2770   Label skip_assignment; |  2770   Label skip_assignment; | 
|  2771   if (instr->hydrogen()->RequiresHoleCheck()) { |  2771   if (instr->hydrogen()->RequiresHoleCheck()) { | 
|  2772     __ CompareRoot(target, Heap::kTheHoleValueRootIndex); |  2772     __ CompareRoot(target, Heap::kTheHoleValueRootIndex); | 
|  2773     if (instr->hydrogen()->DeoptimizesOnHole()) { |  2773     if (instr->hydrogen()->DeoptimizesOnHole()) { | 
|  2774       DeoptimizeIf(equal, instr->environment()); |  2774       DeoptimizeIf(equal, instr->environment()); | 
|  2775     } else { |  2775     } else { | 
|  2776       __ j(not_equal, &skip_assignment); |  2776       __ j(not_equal, &skip_assignment); | 
|  2777     } |  2777     } | 
|  2778   } |  2778   } | 
|  2779   __ movq(target, value); |  2779   __ movp(target, value); | 
|  2780  |  2780  | 
|  2781   if (instr->hydrogen()->NeedsWriteBarrier()) { |  2781   if (instr->hydrogen()->NeedsWriteBarrier()) { | 
|  2782     SmiCheck check_needed = |  2782     SmiCheck check_needed = | 
|  2783       instr->hydrogen()->value()->IsHeapObject() |  2783       instr->hydrogen()->value()->IsHeapObject() | 
|  2784           ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |  2784           ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 
|  2785     int offset = Context::SlotOffset(instr->slot_index()); |  2785     int offset = Context::SlotOffset(instr->slot_index()); | 
|  2786     Register scratch = ToRegister(instr->temp()); |  2786     Register scratch = ToRegister(instr->temp()); | 
|  2787     __ RecordWriteContextSlot(context, |  2787     __ RecordWriteContextSlot(context, | 
|  2788                               offset, |  2788                               offset, | 
|  2789                               value, |  2789                               value, | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
|  2816   Register object = ToRegister(instr->object()); |  2816   Register object = ToRegister(instr->object()); | 
|  2817   if (FLAG_track_double_fields && |  2817   if (FLAG_track_double_fields && | 
|  2818       instr->hydrogen()->representation().IsDouble()) { |  2818       instr->hydrogen()->representation().IsDouble()) { | 
|  2819     XMMRegister result = ToDoubleRegister(instr->result()); |  2819     XMMRegister result = ToDoubleRegister(instr->result()); | 
|  2820     __ movsd(result, FieldOperand(object, offset)); |  2820     __ movsd(result, FieldOperand(object, offset)); | 
|  2821     return; |  2821     return; | 
|  2822   } |  2822   } | 
|  2823  |  2823  | 
|  2824   Register result = ToRegister(instr->result()); |  2824   Register result = ToRegister(instr->result()); | 
|  2825   if (!access.IsInobject()) { |  2825   if (!access.IsInobject()) { | 
|  2826     __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); |  2826     __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset)); | 
|  2827     object = result; |  2827     object = result; | 
|  2828   } |  2828   } | 
|  2829  |  2829  | 
|  2830   Representation representation = access.representation(); |  2830   Representation representation = access.representation(); | 
|  2831   if (representation.IsSmi() && |  2831   if (representation.IsSmi() && | 
|  2832       instr->hydrogen()->representation().IsInteger32()) { |  2832       instr->hydrogen()->representation().IsInteger32()) { | 
|  2833     // Read int value directly from upper half of the smi. |  2833     // Read int value directly from upper half of the smi. | 
|  2834     STATIC_ASSERT(kSmiTag == 0); |  2834     STATIC_ASSERT(kSmiTag == 0); | 
|  2835     STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); |  2835     STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); | 
|  2836     offset += kPointerSize / 2; |  2836     offset += kPointerSize / 2; | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  2859   __ CmpObjectType(function, JS_FUNCTION_TYPE, result); |  2859   __ CmpObjectType(function, JS_FUNCTION_TYPE, result); | 
|  2860   DeoptimizeIf(not_equal, instr->environment()); |  2860   DeoptimizeIf(not_equal, instr->environment()); | 
|  2861  |  2861  | 
|  2862   // Check whether the function has an instance prototype. |  2862   // Check whether the function has an instance prototype. | 
|  2863   Label non_instance; |  2863   Label non_instance; | 
|  2864   __ testb(FieldOperand(result, Map::kBitFieldOffset), |  2864   __ testb(FieldOperand(result, Map::kBitFieldOffset), | 
|  2865            Immediate(1 << Map::kHasNonInstancePrototype)); |  2865            Immediate(1 << Map::kHasNonInstancePrototype)); | 
|  2866   __ j(not_zero, &non_instance, Label::kNear); |  2866   __ j(not_zero, &non_instance, Label::kNear); | 
|  2867  |  2867  | 
|  2868   // Get the prototype or initial map from the function. |  2868   // Get the prototype or initial map from the function. | 
|  2869   __ movq(result, |  2869   __ movp(result, | 
|  2870          FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |  2870          FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 
|  2871  |  2871  | 
|  2872   // Check that the function has a prototype or an initial map. |  2872   // Check that the function has a prototype or an initial map. | 
|  2873   __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |  2873   __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 
|  2874   DeoptimizeIf(equal, instr->environment()); |  2874   DeoptimizeIf(equal, instr->environment()); | 
|  2875  |  2875  | 
|  2876   // If the function does not have an initial map, we're done. |  2876   // If the function does not have an initial map, we're done. | 
|  2877   Label done; |  2877   Label done; | 
|  2878   __ CmpObjectType(result, MAP_TYPE, kScratchRegister); |  2878   __ CmpObjectType(result, MAP_TYPE, kScratchRegister); | 
|  2879   __ j(not_equal, &done, Label::kNear); |  2879   __ j(not_equal, &done, Label::kNear); | 
|  2880  |  2880  | 
|  2881   // Get the prototype from the initial map. |  2881   // Get the prototype from the initial map. | 
|  2882   __ movq(result, FieldOperand(result, Map::kPrototypeOffset)); |  2882   __ movp(result, FieldOperand(result, Map::kPrototypeOffset)); | 
|  2883   __ jmp(&done, Label::kNear); |  2883   __ jmp(&done, Label::kNear); | 
|  2884  |  2884  | 
|  2885   // Non-instance prototype: Fetch prototype from constructor field |  2885   // Non-instance prototype: Fetch prototype from constructor field | 
|  2886   // in the function's map. |  2886   // in the function's map. | 
|  2887   __ bind(&non_instance); |  2887   __ bind(&non_instance); | 
|  2888   __ movq(result, FieldOperand(result, Map::kConstructorOffset)); |  2888   __ movp(result, FieldOperand(result, Map::kConstructorOffset)); | 
|  2889  |  2889  | 
|  2890   // All done. |  2890   // All done. | 
|  2891   __ bind(&done); |  2891   __ bind(&done); | 
|  2892 } |  2892 } | 
|  2893  |  2893  | 
|  2894  |  2894  | 
|  2895 void LCodeGen::DoLoadRoot(LLoadRoot* instr) { |  2895 void LCodeGen::DoLoadRoot(LLoadRoot* instr) { | 
|  2896   Register result = ToRegister(instr->result()); |  2896   Register result = ToRegister(instr->result()); | 
|  2897   __ LoadRoot(result, instr->index()); |  2897   __ LoadRoot(result, instr->index()); | 
|  2898 } |  2898 } | 
|  2899  |  2899  | 
|  2900  |  2900  | 
|  2901 void LCodeGen::DoLoadExternalArrayPointer( |  2901 void LCodeGen::DoLoadExternalArrayPointer( | 
|  2902     LLoadExternalArrayPointer* instr) { |  2902     LLoadExternalArrayPointer* instr) { | 
|  2903   Register result = ToRegister(instr->result()); |  2903   Register result = ToRegister(instr->result()); | 
|  2904   Register input = ToRegister(instr->object()); |  2904   Register input = ToRegister(instr->object()); | 
|  2905   __ movq(result, FieldOperand(input, |  2905   __ movp(result, FieldOperand(input, | 
|  2906                                ExternalPixelArray::kExternalPointerOffset)); |  2906                                ExternalPixelArray::kExternalPointerOffset)); | 
|  2907 } |  2907 } | 
|  2908  |  2908  | 
|  2909  |  2909  | 
|  2910 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |  2910 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { | 
|  2911   Register arguments = ToRegister(instr->arguments()); |  2911   Register arguments = ToRegister(instr->arguments()); | 
|  2912   Register result = ToRegister(instr->result()); |  2912   Register result = ToRegister(instr->result()); | 
|  2913  |  2913  | 
|  2914   if (instr->length()->IsConstantOperand() && |  2914   if (instr->length()->IsConstantOperand() && | 
|  2915       instr->index()->IsConstantOperand()) { |  2915       instr->index()->IsConstantOperand()) { | 
|  2916     int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); |  2916     int32_t const_index = ToInteger32(LConstantOperand::cast(instr->index())); | 
|  2917     int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length())); |  2917     int32_t const_length = ToInteger32(LConstantOperand::cast(instr->length())); | 
|  2918     StackArgumentsAccessor args(arguments, const_length, |  2918     StackArgumentsAccessor args(arguments, const_length, | 
|  2919                                 ARGUMENTS_DONT_CONTAIN_RECEIVER); |  2919                                 ARGUMENTS_DONT_CONTAIN_RECEIVER); | 
|  2920     __ movq(result, args.GetArgumentOperand(const_index)); |  2920     __ movp(result, args.GetArgumentOperand(const_index)); | 
|  2921   } else { |  2921   } else { | 
|  2922     Register length = ToRegister(instr->length()); |  2922     Register length = ToRegister(instr->length()); | 
|  2923     // There are two words between the frame pointer and the last argument. |  2923     // There are two words between the frame pointer and the last argument. | 
|  2924     // Subtracting from length accounts for one of them add one more. |  2924     // Subtracting from length accounts for one of them add one more. | 
|  2925     if (instr->index()->IsRegister()) { |  2925     if (instr->index()->IsRegister()) { | 
|  2926       __ subl(length, ToRegister(instr->index())); |  2926       __ subl(length, ToRegister(instr->index())); | 
|  2927     } else { |  2927     } else { | 
|  2928       __ subl(length, ToOperand(instr->index())); |  2928       __ subl(length, ToOperand(instr->index())); | 
|  2929     } |  2929     } | 
|  2930     StackArgumentsAccessor args(arguments, length, |  2930     StackArgumentsAccessor args(arguments, length, | 
|  2931                                 ARGUMENTS_DONT_CONTAIN_RECEIVER); |  2931                                 ARGUMENTS_DONT_CONTAIN_RECEIVER); | 
|  2932     __ movq(result, args.GetArgumentOperand(0)); |  2932     __ movp(result, args.GetArgumentOperand(0)); | 
|  2933   } |  2933   } | 
|  2934 } |  2934 } | 
|  2935  |  2935  | 
|  2936  |  2936  | 
|  2937 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |  2937 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 
|  2938   ElementsKind elements_kind = instr->elements_kind(); |  2938   ElementsKind elements_kind = instr->elements_kind(); | 
|  2939   LOperand* key = instr->key(); |  2939   LOperand* key = instr->key(); | 
|  2940   if (!key->IsConstantOperand()) { |  2940   if (!key->IsConstantOperand()) { | 
|  2941     Register key_reg = ToRegister(key); |  2941     Register key_reg = ToRegister(key); | 
|  2942     // Even though the HLoad/StoreKeyed (in this case) instructions force |  2942     // Even though the HLoad/StoreKeyed (in this case) instructions force | 
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3159  |  3159  | 
|  3160  |  3160  | 
|  3161 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { |  3161 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { | 
|  3162   Register result = ToRegister(instr->result()); |  3162   Register result = ToRegister(instr->result()); | 
|  3163  |  3163  | 
|  3164   if (instr->hydrogen()->from_inlined()) { |  3164   if (instr->hydrogen()->from_inlined()) { | 
|  3165     __ lea(result, Operand(rsp, -kFPOnStackSize + -kPCOnStackSize)); |  3165     __ lea(result, Operand(rsp, -kFPOnStackSize + -kPCOnStackSize)); | 
|  3166   } else { |  3166   } else { | 
|  3167     // Check for arguments adapter frame. |  3167     // Check for arguments adapter frame. | 
|  3168     Label done, adapted; |  3168     Label done, adapted; | 
|  3169     __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |  3169     __ movp(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
|  3170     __ Cmp(Operand(result, StandardFrameConstants::kContextOffset), |  3170     __ Cmp(Operand(result, StandardFrameConstants::kContextOffset), | 
|  3171            Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |  3171            Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
|  3172     __ j(equal, &adapted, Label::kNear); |  3172     __ j(equal, &adapted, Label::kNear); | 
|  3173  |  3173  | 
|  3174     // No arguments adaptor frame. |  3174     // No arguments adaptor frame. | 
|  3175     __ movq(result, rbp); |  3175     __ movp(result, rbp); | 
|  3176     __ jmp(&done, Label::kNear); |  3176     __ jmp(&done, Label::kNear); | 
|  3177  |  3177  | 
|  3178     // Arguments adaptor frame present. |  3178     // Arguments adaptor frame present. | 
|  3179     __ bind(&adapted); |  3179     __ bind(&adapted); | 
|  3180     __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |  3180     __ movp(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
|  3181  |  3181  | 
|  3182     // Result is the frame pointer for the frame if not adapted and for the real |  3182     // Result is the frame pointer for the frame if not adapted and for the real | 
|  3183     // frame below the adaptor frame if adapted. |  3183     // frame below the adaptor frame if adapted. | 
|  3184     __ bind(&done); |  3184     __ bind(&done); | 
|  3185   } |  3185   } | 
|  3186 } |  3186 } | 
|  3187  |  3187  | 
|  3188  |  3188  | 
|  3189 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { |  3189 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { | 
|  3190   Register result = ToRegister(instr->result()); |  3190   Register result = ToRegister(instr->result()); | 
|  3191  |  3191  | 
|  3192   Label done; |  3192   Label done; | 
|  3193  |  3193  | 
|  3194   // If no arguments adaptor frame the number of arguments is fixed. |  3194   // If no arguments adaptor frame the number of arguments is fixed. | 
|  3195   if (instr->elements()->IsRegister()) { |  3195   if (instr->elements()->IsRegister()) { | 
|  3196     __ cmpq(rbp, ToRegister(instr->elements())); |  3196     __ cmpq(rbp, ToRegister(instr->elements())); | 
|  3197   } else { |  3197   } else { | 
|  3198     __ cmpq(rbp, ToOperand(instr->elements())); |  3198     __ cmpq(rbp, ToOperand(instr->elements())); | 
|  3199   } |  3199   } | 
|  3200   __ movl(result, Immediate(scope()->num_parameters())); |  3200   __ movl(result, Immediate(scope()->num_parameters())); | 
|  3201   __ j(equal, &done, Label::kNear); |  3201   __ j(equal, &done, Label::kNear); | 
|  3202  |  3202  | 
|  3203   // Arguments adaptor frame present. Get argument length from there. |  3203   // Arguments adaptor frame present. Get argument length from there. | 
|  3204   __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |  3204   __ movp(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
|  3205   __ SmiToInteger32(result, |  3205   __ SmiToInteger32(result, | 
|  3206                     Operand(result, |  3206                     Operand(result, | 
|  3207                             ArgumentsAdaptorFrameConstants::kLengthOffset)); |  3207                             ArgumentsAdaptorFrameConstants::kLengthOffset)); | 
|  3208  |  3208  | 
|  3209   // Argument length is in result register. |  3209   // Argument length is in result register. | 
|  3210   __ bind(&done); |  3210   __ bind(&done); | 
|  3211 } |  3211 } | 
|  3212  |  3212  | 
|  3213  |  3213  | 
|  3214 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { |  3214 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { | 
|  3215   Register receiver = ToRegister(instr->receiver()); |  3215   Register receiver = ToRegister(instr->receiver()); | 
|  3216   Register function = ToRegister(instr->function()); |  3216   Register function = ToRegister(instr->function()); | 
|  3217  |  3217  | 
|  3218   // If the receiver is null or undefined, we have to pass the global |  3218   // If the receiver is null or undefined, we have to pass the global | 
|  3219   // object as a receiver to normal functions. Values have to be |  3219   // object as a receiver to normal functions. Values have to be | 
|  3220   // passed unchanged to builtins and strict-mode functions. |  3220   // passed unchanged to builtins and strict-mode functions. | 
|  3221   Label global_object, receiver_ok; |  3221   Label global_object, receiver_ok; | 
|  3222   Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; |  3222   Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; | 
|  3223  |  3223  | 
|  3224   // Do not transform the receiver to object for strict mode |  3224   // Do not transform the receiver to object for strict mode | 
|  3225   // functions. |  3225   // functions. | 
|  3226   __ movq(kScratchRegister, |  3226   __ movp(kScratchRegister, | 
|  3227           FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); |  3227           FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 
|  3228   __ testb(FieldOperand(kScratchRegister, |  3228   __ testb(FieldOperand(kScratchRegister, | 
|  3229                         SharedFunctionInfo::kStrictModeByteOffset), |  3229                         SharedFunctionInfo::kStrictModeByteOffset), | 
|  3230            Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte)); |  3230            Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte)); | 
|  3231   __ j(not_equal, &receiver_ok, dist); |  3231   __ j(not_equal, &receiver_ok, dist); | 
|  3232  |  3232  | 
|  3233   // Do not transform the receiver to object for builtins. |  3233   // Do not transform the receiver to object for builtins. | 
|  3234   __ testb(FieldOperand(kScratchRegister, |  3234   __ testb(FieldOperand(kScratchRegister, | 
|  3235                         SharedFunctionInfo::kNativeByteOffset), |  3235                         SharedFunctionInfo::kNativeByteOffset), | 
|  3236            Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte)); |  3236            Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte)); | 
|  3237   __ j(not_equal, &receiver_ok, dist); |  3237   __ j(not_equal, &receiver_ok, dist); | 
|  3238  |  3238  | 
|  3239   // Normal function. Replace undefined or null with global receiver. |  3239   // Normal function. Replace undefined or null with global receiver. | 
|  3240   __ CompareRoot(receiver, Heap::kNullValueRootIndex); |  3240   __ CompareRoot(receiver, Heap::kNullValueRootIndex); | 
|  3241   __ j(equal, &global_object, Label::kNear); |  3241   __ j(equal, &global_object, Label::kNear); | 
|  3242   __ CompareRoot(receiver, Heap::kUndefinedValueRootIndex); |  3242   __ CompareRoot(receiver, Heap::kUndefinedValueRootIndex); | 
|  3243   __ j(equal, &global_object, Label::kNear); |  3243   __ j(equal, &global_object, Label::kNear); | 
|  3244  |  3244  | 
|  3245   // The receiver should be a JS object. |  3245   // The receiver should be a JS object. | 
|  3246   Condition is_smi = __ CheckSmi(receiver); |  3246   Condition is_smi = __ CheckSmi(receiver); | 
|  3247   DeoptimizeIf(is_smi, instr->environment()); |  3247   DeoptimizeIf(is_smi, instr->environment()); | 
|  3248   __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister); |  3248   __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister); | 
|  3249   DeoptimizeIf(below, instr->environment()); |  3249   DeoptimizeIf(below, instr->environment()); | 
|  3250   __ jmp(&receiver_ok, Label::kNear); |  3250   __ jmp(&receiver_ok, Label::kNear); | 
|  3251  |  3251  | 
|  3252   __ bind(&global_object); |  3252   __ bind(&global_object); | 
|  3253   __ movq(receiver, FieldOperand(function, JSFunction::kContextOffset)); |  3253   __ movp(receiver, FieldOperand(function, JSFunction::kContextOffset)); | 
|  3254   __ movq(receiver, |  3254   __ movp(receiver, | 
|  3255           Operand(receiver, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |  3255           Operand(receiver, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 
|  3256   __ movq(receiver, |  3256   __ movp(receiver, | 
|  3257           FieldOperand(receiver, GlobalObject::kGlobalReceiverOffset)); |  3257           FieldOperand(receiver, GlobalObject::kGlobalReceiverOffset)); | 
|  3258   __ bind(&receiver_ok); |  3258   __ bind(&receiver_ok); | 
|  3259 } |  3259 } | 
|  3260  |  3260  | 
|  3261  |  3261  | 
|  3262 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |  3262 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 
|  3263   Register receiver = ToRegister(instr->receiver()); |  3263   Register receiver = ToRegister(instr->receiver()); | 
|  3264   Register function = ToRegister(instr->function()); |  3264   Register function = ToRegister(instr->function()); | 
|  3265   Register length = ToRegister(instr->length()); |  3265   Register length = ToRegister(instr->length()); | 
|  3266   Register elements = ToRegister(instr->elements()); |  3266   Register elements = ToRegister(instr->elements()); | 
|  3267   ASSERT(receiver.is(rax));  // Used for parameter count. |  3267   ASSERT(receiver.is(rax));  // Used for parameter count. | 
|  3268   ASSERT(function.is(rdi));  // Required by InvokeFunction. |  3268   ASSERT(function.is(rdi));  // Required by InvokeFunction. | 
|  3269   ASSERT(ToRegister(instr->result()).is(rax)); |  3269   ASSERT(ToRegister(instr->result()).is(rax)); | 
|  3270  |  3270  | 
|  3271   // Copy the arguments to this function possibly from the |  3271   // Copy the arguments to this function possibly from the | 
|  3272   // adaptor frame below it. |  3272   // adaptor frame below it. | 
|  3273   const uint32_t kArgumentsLimit = 1 * KB; |  3273   const uint32_t kArgumentsLimit = 1 * KB; | 
|  3274   __ cmpq(length, Immediate(kArgumentsLimit)); |  3274   __ cmpq(length, Immediate(kArgumentsLimit)); | 
|  3275   DeoptimizeIf(above, instr->environment()); |  3275   DeoptimizeIf(above, instr->environment()); | 
|  3276  |  3276  | 
|  3277   __ push(receiver); |  3277   __ push(receiver); | 
|  3278   __ movq(receiver, length); |  3278   __ movp(receiver, length); | 
|  3279  |  3279  | 
|  3280   // Loop through the arguments pushing them onto the execution |  3280   // Loop through the arguments pushing them onto the execution | 
|  3281   // stack. |  3281   // stack. | 
|  3282   Label invoke, loop; |  3282   Label invoke, loop; | 
|  3283   // length is a small non-negative integer, due to the test above. |  3283   // length is a small non-negative integer, due to the test above. | 
|  3284   __ testl(length, length); |  3284   __ testl(length, length); | 
|  3285   __ j(zero, &invoke, Label::kNear); |  3285   __ j(zero, &invoke, Label::kNear); | 
|  3286   __ bind(&loop); |  3286   __ bind(&loop); | 
|  3287   StackArgumentsAccessor args(elements, length, |  3287   StackArgumentsAccessor args(elements, length, | 
|  3288                               ARGUMENTS_DONT_CONTAIN_RECEIVER); |  3288                               ARGUMENTS_DONT_CONTAIN_RECEIVER); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|  3307 } |  3307 } | 
|  3308  |  3308  | 
|  3309  |  3309  | 
|  3310 void LCodeGen::DoDrop(LDrop* instr) { |  3310 void LCodeGen::DoDrop(LDrop* instr) { | 
|  3311   __ Drop(instr->count()); |  3311   __ Drop(instr->count()); | 
|  3312 } |  3312 } | 
|  3313  |  3313  | 
|  3314  |  3314  | 
|  3315 void LCodeGen::DoThisFunction(LThisFunction* instr) { |  3315 void LCodeGen::DoThisFunction(LThisFunction* instr) { | 
|  3316   Register result = ToRegister(instr->result()); |  3316   Register result = ToRegister(instr->result()); | 
|  3317   __ movq(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |  3317   __ movp(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 
|  3318 } |  3318 } | 
|  3319  |  3319  | 
|  3320  |  3320  | 
|  3321 void LCodeGen::DoContext(LContext* instr) { |  3321 void LCodeGen::DoContext(LContext* instr) { | 
|  3322   Register result = ToRegister(instr->result()); |  3322   Register result = ToRegister(instr->result()); | 
|  3323   if (info()->IsOptimizing()) { |  3323   if (info()->IsOptimizing()) { | 
|  3324     __ movq(result, Operand(rbp, StandardFrameConstants::kContextOffset)); |  3324     __ movp(result, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  3325   } else { |  3325   } else { | 
|  3326     // If there is no frame, the context must be in rsi. |  3326     // If there is no frame, the context must be in rsi. | 
|  3327     ASSERT(result.is(rsi)); |  3327     ASSERT(result.is(rsi)); | 
|  3328   } |  3328   } | 
|  3329 } |  3329 } | 
|  3330  |  3330  | 
|  3331  |  3331  | 
|  3332 void LCodeGen::DoOuterContext(LOuterContext* instr) { |  3332 void LCodeGen::DoOuterContext(LOuterContext* instr) { | 
|  3333   Register context = ToRegister(instr->context()); |  3333   Register context = ToRegister(instr->context()); | 
|  3334   Register result = ToRegister(instr->result()); |  3334   Register result = ToRegister(instr->result()); | 
|  3335   __ movq(result, |  3335   __ movp(result, | 
|  3336           Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); |  3336           Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); | 
|  3337 } |  3337 } | 
|  3338  |  3338  | 
|  3339  |  3339  | 
|  3340 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { |  3340 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { | 
|  3341   ASSERT(ToRegister(instr->context()).is(rsi)); |  3341   ASSERT(ToRegister(instr->context()).is(rsi)); | 
|  3342   __ push(rsi);  // The context is the first argument. |  3342   __ push(rsi);  // The context is the first argument. | 
|  3343   __ Push(instr->hydrogen()->pairs()); |  3343   __ Push(instr->hydrogen()->pairs()); | 
|  3344   __ Push(Smi::FromInt(instr->hydrogen()->flags())); |  3344   __ Push(Smi::FromInt(instr->hydrogen()->flags())); | 
|  3345   CallRuntime(Runtime::kDeclareGlobals, 3, instr); |  3345   CallRuntime(Runtime::kDeclareGlobals, 3, instr); | 
|  3346 } |  3346 } | 
|  3347  |  3347  | 
|  3348  |  3348  | 
|  3349 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { |  3349 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { | 
|  3350   Register context = ToRegister(instr->context()); |  3350   Register context = ToRegister(instr->context()); | 
|  3351   Register result = ToRegister(instr->result()); |  3351   Register result = ToRegister(instr->result()); | 
|  3352   __ movq(result, |  3352   __ movp(result, | 
|  3353           Operand(context, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |  3353           Operand(context, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 
|  3354 } |  3354 } | 
|  3355  |  3355  | 
|  3356  |  3356  | 
|  3357 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |  3357 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 
|  3358   Register global = ToRegister(instr->global()); |  3358   Register global = ToRegister(instr->global()); | 
|  3359   Register result = ToRegister(instr->result()); |  3359   Register result = ToRegister(instr->result()); | 
|  3360   __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); |  3360   __ movp(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); | 
|  3361 } |  3361 } | 
|  3362  |  3362  | 
|  3363  |  3363  | 
|  3364 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |  3364 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 
|  3365                                  int formal_parameter_count, |  3365                                  int formal_parameter_count, | 
|  3366                                  int arity, |  3366                                  int arity, | 
|  3367                                  LInstruction* instr, |  3367                                  LInstruction* instr, | 
|  3368                                  RDIState rdi_state) { |  3368                                  RDIState rdi_state) { | 
|  3369   bool dont_adapt_arguments = |  3369   bool dont_adapt_arguments = | 
|  3370       formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |  3370       formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 
|  3371   bool can_invoke_directly = |  3371   bool can_invoke_directly = | 
|  3372       dont_adapt_arguments || formal_parameter_count == arity; |  3372       dont_adapt_arguments || formal_parameter_count == arity; | 
|  3373  |  3373  | 
|  3374   LPointerMap* pointers = instr->pointer_map(); |  3374   LPointerMap* pointers = instr->pointer_map(); | 
|  3375  |  3375  | 
|  3376   if (can_invoke_directly) { |  3376   if (can_invoke_directly) { | 
|  3377     if (rdi_state == RDI_UNINITIALIZED) { |  3377     if (rdi_state == RDI_UNINITIALIZED) { | 
|  3378       __ Move(rdi, function); |  3378       __ Move(rdi, function); | 
|  3379     } |  3379     } | 
|  3380  |  3380  | 
|  3381     // Change context. |  3381     // Change context. | 
|  3382     __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |  3382     __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 
|  3383  |  3383  | 
|  3384     // Set rax to arguments count if adaption is not needed. Assumes that rax |  3384     // Set rax to arguments count if adaption is not needed. Assumes that rax | 
|  3385     // is available to write to at this point. |  3385     // is available to write to at this point. | 
|  3386     if (dont_adapt_arguments) { |  3386     if (dont_adapt_arguments) { | 
|  3387       __ Set(rax, arity); |  3387       __ Set(rax, arity); | 
|  3388     } |  3388     } | 
|  3389  |  3389  | 
|  3390     // Invoke function. |  3390     // Invoke function. | 
|  3391     if (function.is_identical_to(info()->closure())) { |  3391     if (function.is_identical_to(info()->closure())) { | 
|  3392       __ CallSelf(); |  3392       __ CallSelf(); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3431  |  3431  | 
|  3432 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { |  3432 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { | 
|  3433   ASSERT(ToRegister(instr->function()).is(rdi)); |  3433   ASSERT(ToRegister(instr->function()).is(rdi)); | 
|  3434   ASSERT(ToRegister(instr->result()).is(rax)); |  3434   ASSERT(ToRegister(instr->result()).is(rax)); | 
|  3435  |  3435  | 
|  3436   if (instr->hydrogen()->pass_argument_count()) { |  3436   if (instr->hydrogen()->pass_argument_count()) { | 
|  3437     __ Set(rax, instr->arity()); |  3437     __ Set(rax, instr->arity()); | 
|  3438   } |  3438   } | 
|  3439  |  3439  | 
|  3440   // Change context. |  3440   // Change context. | 
|  3441   __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |  3441   __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 
|  3442  |  3442  | 
|  3443   LPointerMap* pointers = instr->pointer_map(); |  3443   LPointerMap* pointers = instr->pointer_map(); | 
|  3444   SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |  3444   SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 
|  3445  |  3445  | 
|  3446   bool is_self_call = false; |  3446   bool is_self_call = false; | 
|  3447   if (instr->hydrogen()->function()->IsConstant()) { |  3447   if (instr->hydrogen()->function()->IsConstant()) { | 
|  3448     Handle<JSFunction> jsfun = Handle<JSFunction>::null(); |  3448     Handle<JSFunction> jsfun = Handle<JSFunction>::null(); | 
|  3449     HConstant* fun_const = HConstant::cast(instr->hydrogen()->function()); |  3449     HConstant* fun_const = HConstant::cast(instr->hydrogen()->function()); | 
|  3450     jsfun = Handle<JSFunction>::cast(fun_const->handle(isolate())); |  3450     jsfun = Handle<JSFunction>::cast(fun_const->handle(isolate())); | 
|  3451     is_self_call = jsfun.is_identical_to(info()->closure()); |  3451     is_self_call = jsfun.is_identical_to(info()->closure()); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3484   __ j(zero, &done); |  3484   __ j(zero, &done); | 
|  3485  |  3485  | 
|  3486   __ AllocateHeapNumber(tmp, tmp2, &slow); |  3486   __ AllocateHeapNumber(tmp, tmp2, &slow); | 
|  3487   __ jmp(&allocated, Label::kNear); |  3487   __ jmp(&allocated, Label::kNear); | 
|  3488  |  3488  | 
|  3489   // Slow case: Call the runtime system to do the number allocation. |  3489   // Slow case: Call the runtime system to do the number allocation. | 
|  3490   __ bind(&slow); |  3490   __ bind(&slow); | 
|  3491   CallRuntimeFromDeferred( |  3491   CallRuntimeFromDeferred( | 
|  3492       Runtime::kAllocateHeapNumber, 0, instr, instr->context()); |  3492       Runtime::kAllocateHeapNumber, 0, instr, instr->context()); | 
|  3493   // Set the pointer to the new heap number in tmp. |  3493   // Set the pointer to the new heap number in tmp. | 
|  3494   if (!tmp.is(rax)) __ movq(tmp, rax); |  3494   if (!tmp.is(rax)) __ movp(tmp, rax); | 
|  3495   // Restore input_reg after call to runtime. |  3495   // Restore input_reg after call to runtime. | 
|  3496   __ LoadFromSafepointRegisterSlot(input_reg, input_reg); |  3496   __ LoadFromSafepointRegisterSlot(input_reg, input_reg); | 
|  3497  |  3497  | 
|  3498   __ bind(&allocated); |  3498   __ bind(&allocated); | 
|  3499   __ MoveDouble(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); |  3499   __ MoveDouble(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 
|  3500   __ shl(tmp2, Immediate(1)); |  3500   __ shl(tmp2, Immediate(1)); | 
|  3501   __ shr(tmp2, Immediate(1)); |  3501   __ shr(tmp2, Immediate(1)); | 
|  3502   __ MoveDouble(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); |  3502   __ MoveDouble(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); | 
|  3503   __ StoreToSafepointRegisterSlot(input_reg, tmp); |  3503   __ StoreToSafepointRegisterSlot(input_reg, tmp); | 
|  3504  |  3504  | 
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3872  |  3872  | 
|  3873   if (instr->arity() == 0) { |  3873   if (instr->arity() == 0) { | 
|  3874     ArrayNoArgumentConstructorStub stub(kind, override_mode); |  3874     ArrayNoArgumentConstructorStub stub(kind, override_mode); | 
|  3875     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |  3875     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 
|  3876   } else if (instr->arity() == 1) { |  3876   } else if (instr->arity() == 1) { | 
|  3877     Label done; |  3877     Label done; | 
|  3878     if (IsFastPackedElementsKind(kind)) { |  3878     if (IsFastPackedElementsKind(kind)) { | 
|  3879       Label packed_case; |  3879       Label packed_case; | 
|  3880       // We might need a change here |  3880       // We might need a change here | 
|  3881       // look at the first argument |  3881       // look at the first argument | 
|  3882       __ movq(rcx, Operand(rsp, 0)); |  3882       __ movp(rcx, Operand(rsp, 0)); | 
|  3883       __ testq(rcx, rcx); |  3883       __ testq(rcx, rcx); | 
|  3884       __ j(zero, &packed_case, Label::kNear); |  3884       __ j(zero, &packed_case, Label::kNear); | 
|  3885  |  3885  | 
|  3886       ElementsKind holey_kind = GetHoleyElementsKind(kind); |  3886       ElementsKind holey_kind = GetHoleyElementsKind(kind); | 
|  3887       ArraySingleArgumentConstructorStub stub(holey_kind, override_mode); |  3887       ArraySingleArgumentConstructorStub stub(holey_kind, override_mode); | 
|  3888       CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |  3888       CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 
|  3889       __ jmp(&done, Label::kNear); |  3889       __ jmp(&done, Label::kNear); | 
|  3890       __ bind(&packed_case); |  3890       __ bind(&packed_case); | 
|  3891     } |  3891     } | 
|  3892  |  3892  | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  3903 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |  3903 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 
|  3904   ASSERT(ToRegister(instr->context()).is(rsi)); |  3904   ASSERT(ToRegister(instr->context()).is(rsi)); | 
|  3905   CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); |  3905   CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); | 
|  3906 } |  3906 } | 
|  3907  |  3907  | 
|  3908  |  3908  | 
|  3909 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { |  3909 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { | 
|  3910   Register function = ToRegister(instr->function()); |  3910   Register function = ToRegister(instr->function()); | 
|  3911   Register code_object = ToRegister(instr->code_object()); |  3911   Register code_object = ToRegister(instr->code_object()); | 
|  3912   __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize)); |  3912   __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize)); | 
|  3913   __ movq(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object); |  3913   __ movp(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object); | 
|  3914 } |  3914 } | 
|  3915  |  3915  | 
|  3916  |  3916  | 
|  3917 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |  3917 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { | 
|  3918   Register result = ToRegister(instr->result()); |  3918   Register result = ToRegister(instr->result()); | 
|  3919   Register base = ToRegister(instr->base_object()); |  3919   Register base = ToRegister(instr->base_object()); | 
|  3920   if (instr->offset()->IsConstantOperand()) { |  3920   if (instr->offset()->IsConstantOperand()) { | 
|  3921     LConstantOperand* offset = LConstantOperand::cast(instr->offset()); |  3921     LConstantOperand* offset = LConstantOperand::cast(instr->offset()); | 
|  3922     __ lea(result, Operand(base, ToInteger32(offset))); |  3922     __ lea(result, Operand(base, ToInteger32(offset))); | 
|  3923   } else { |  3923   } else { | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3981     __ movsd(FieldOperand(object, offset), value); |  3981     __ movsd(FieldOperand(object, offset), value); | 
|  3982     return; |  3982     return; | 
|  3983   } |  3983   } | 
|  3984  |  3984  | 
|  3985   if (!transition.is_null()) { |  3985   if (!transition.is_null()) { | 
|  3986     if (!hinstr->NeedsWriteBarrierForMap()) { |  3986     if (!hinstr->NeedsWriteBarrierForMap()) { | 
|  3987       __ Move(FieldOperand(object, HeapObject::kMapOffset), transition); |  3987       __ Move(FieldOperand(object, HeapObject::kMapOffset), transition); | 
|  3988     } else { |  3988     } else { | 
|  3989       Register temp = ToRegister(instr->temp()); |  3989       Register temp = ToRegister(instr->temp()); | 
|  3990       __ Move(kScratchRegister, transition); |  3990       __ Move(kScratchRegister, transition); | 
|  3991       __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); |  3991       __ movp(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); | 
|  3992       // Update the write barrier for the map field. |  3992       // Update the write barrier for the map field. | 
|  3993       __ RecordWriteField(object, |  3993       __ RecordWriteField(object, | 
|  3994                           HeapObject::kMapOffset, |  3994                           HeapObject::kMapOffset, | 
|  3995                           kScratchRegister, |  3995                           kScratchRegister, | 
|  3996                           temp, |  3996                           temp, | 
|  3997                           kSaveFPRegs, |  3997                           kSaveFPRegs, | 
|  3998                           OMIT_REMEMBERED_SET, |  3998                           OMIT_REMEMBERED_SET, | 
|  3999                           OMIT_SMI_CHECK); |  3999                           OMIT_SMI_CHECK); | 
|  4000     } |  4000     } | 
|  4001   } |  4001   } | 
|  4002  |  4002  | 
|  4003   // Do the store. |  4003   // Do the store. | 
|  4004   SmiCheck check_needed = hinstr->value()->IsHeapObject() |  4004   SmiCheck check_needed = hinstr->value()->IsHeapObject() | 
|  4005                           ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |  4005                           ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 
|  4006  |  4006  | 
|  4007   Register write_register = object; |  4007   Register write_register = object; | 
|  4008   if (!access.IsInobject()) { |  4008   if (!access.IsInobject()) { | 
|  4009     write_register = ToRegister(instr->temp()); |  4009     write_register = ToRegister(instr->temp()); | 
|  4010     __ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); |  4010     __ movp(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); | 
|  4011   } |  4011   } | 
|  4012  |  4012  | 
|  4013   if (representation.IsSmi() && |  4013   if (representation.IsSmi() && | 
|  4014       hinstr->value()->representation().IsInteger32()) { |  4014       hinstr->value()->representation().IsInteger32()) { | 
|  4015     ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); |  4015     ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); | 
|  4016     // Store int value directly to upper half of the smi. |  4016     // Store int value directly to upper half of the smi. | 
|  4017     STATIC_ASSERT(kSmiTag == 0); |  4017     STATIC_ASSERT(kSmiTag == 0); | 
|  4018     STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); |  4018     STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); | 
|  4019     offset += kPointerSize / 2; |  4019     offset += kPointerSize / 2; | 
|  4020     representation = Representation::Integer32(); |  4020     representation = Representation::Integer32(); | 
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4348   Handle<Map> to_map = instr->transitioned_map(); |  4348   Handle<Map> to_map = instr->transitioned_map(); | 
|  4349   ElementsKind from_kind = instr->from_kind(); |  4349   ElementsKind from_kind = instr->from_kind(); | 
|  4350   ElementsKind to_kind = instr->to_kind(); |  4350   ElementsKind to_kind = instr->to_kind(); | 
|  4351  |  4351  | 
|  4352   Label not_applicable; |  4352   Label not_applicable; | 
|  4353   __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); |  4353   __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); | 
|  4354   __ j(not_equal, ¬_applicable); |  4354   __ j(not_equal, ¬_applicable); | 
|  4355   if (IsSimpleMapChangeTransition(from_kind, to_kind)) { |  4355   if (IsSimpleMapChangeTransition(from_kind, to_kind)) { | 
|  4356     Register new_map_reg = ToRegister(instr->new_map_temp()); |  4356     Register new_map_reg = ToRegister(instr->new_map_temp()); | 
|  4357     __ Move(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); |  4357     __ Move(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); | 
|  4358     __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); |  4358     __ movp(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); | 
|  4359     // Write barrier. |  4359     // Write barrier. | 
|  4360     ASSERT_NE(instr->temp(), NULL); |  4360     ASSERT_NE(instr->temp(), NULL); | 
|  4361     __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, |  4361     __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, | 
|  4362                         ToRegister(instr->temp()), kDontSaveFPRegs); |  4362                         ToRegister(instr->temp()), kDontSaveFPRegs); | 
|  4363   } else { |  4363   } else { | 
|  4364     ASSERT(ToRegister(instr->context()).is(rsi)); |  4364     ASSERT(ToRegister(instr->context()).is(rsi)); | 
|  4365     PushSafepointRegistersScope scope(this); |  4365     PushSafepointRegistersScope scope(this); | 
|  4366     if (!object_reg.is(rax)) { |  4366     if (!object_reg.is(rax)) { | 
|  4367       __ movq(rax, object_reg); |  4367       __ movp(rax, object_reg); | 
|  4368     } |  4368     } | 
|  4369     __ Move(rbx, to_map); |  4369     __ Move(rbx, to_map); | 
|  4370     TransitionElementsKindStub stub(from_kind, to_kind); |  4370     TransitionElementsKindStub stub(from_kind, to_kind); | 
|  4371     __ CallStub(&stub); |  4371     __ CallStub(&stub); | 
|  4372     RecordSafepointWithRegisters( |  4372     RecordSafepointWithRegisters( | 
|  4373         instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |  4373         instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 
|  4374   } |  4374   } | 
|  4375   __ bind(¬_applicable); |  4375   __ bind(¬_applicable); | 
|  4376 } |  4376 } | 
|  4377  |  4377  | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4476  |  4476  | 
|  4477   ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); |  4477   ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); | 
|  4478   Register char_code = ToRegister(instr->char_code()); |  4478   Register char_code = ToRegister(instr->char_code()); | 
|  4479   Register result = ToRegister(instr->result()); |  4479   Register result = ToRegister(instr->result()); | 
|  4480   ASSERT(!char_code.is(result)); |  4480   ASSERT(!char_code.is(result)); | 
|  4481  |  4481  | 
|  4482   __ cmpl(char_code, Immediate(String::kMaxOneByteCharCode)); |  4482   __ cmpl(char_code, Immediate(String::kMaxOneByteCharCode)); | 
|  4483   __ j(above, deferred->entry()); |  4483   __ j(above, deferred->entry()); | 
|  4484   __ movsxlq(char_code, char_code); |  4484   __ movsxlq(char_code, char_code); | 
|  4485   __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); |  4485   __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); | 
|  4486   __ movq(result, FieldOperand(result, |  4486   __ movp(result, FieldOperand(result, | 
|  4487                                char_code, times_pointer_size, |  4487                                char_code, times_pointer_size, | 
|  4488                                FixedArray::kHeaderSize)); |  4488                                FixedArray::kHeaderSize)); | 
|  4489   __ CompareRoot(result, Heap::kUndefinedValueRootIndex); |  4489   __ CompareRoot(result, Heap::kUndefinedValueRootIndex); | 
|  4490   __ j(equal, deferred->entry()); |  4490   __ j(equal, deferred->entry()); | 
|  4491   __ bind(deferred->exit()); |  4491   __ bind(deferred->exit()); | 
|  4492 } |  4492 } | 
|  4493  |  4493  | 
|  4494  |  4494  | 
|  4495 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { |  4495 void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { | 
|  4496   Register char_code = ToRegister(instr->char_code()); |  4496   Register char_code = ToRegister(instr->char_code()); | 
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4622   // Put a valid pointer value in the stack slot where the result |  4622   // Put a valid pointer value in the stack slot where the result | 
|  4623   // register is stored, as this register is in the pointer map, but contains an |  4623   // register is stored, as this register is in the pointer map, but contains an | 
|  4624   // integer value. |  4624   // integer value. | 
|  4625   __ StoreToSafepointRegisterSlot(reg, Immediate(0)); |  4625   __ StoreToSafepointRegisterSlot(reg, Immediate(0)); | 
|  4626  |  4626  | 
|  4627   // NumberTagU uses the context from the frame, rather than |  4627   // NumberTagU uses the context from the frame, rather than | 
|  4628   // the environment's HContext or HInlinedContext value. |  4628   // the environment's HContext or HInlinedContext value. | 
|  4629   // They only call Runtime::kAllocateHeapNumber. |  4629   // They only call Runtime::kAllocateHeapNumber. | 
|  4630   // The corresponding HChange instructions are added in a phase that does |  4630   // The corresponding HChange instructions are added in a phase that does | 
|  4631   // not have easy access to the local context. |  4631   // not have easy access to the local context. | 
|  4632   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  4632   __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  4633   __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |  4633   __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 
|  4634   RecordSafepointWithRegisters( |  4634   RecordSafepointWithRegisters( | 
|  4635       instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |  4635       instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 
|  4636  |  4636  | 
|  4637   if (!reg.is(rax)) __ movq(reg, rax); |  4637   if (!reg.is(rax)) __ movp(reg, rax); | 
|  4638  |  4638  | 
|  4639   // Done. Put the value in temp_xmm into the value of the allocated heap |  4639   // Done. Put the value in temp_xmm into the value of the allocated heap | 
|  4640   // number. |  4640   // number. | 
|  4641   __ bind(&done); |  4641   __ bind(&done); | 
|  4642   __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm); |  4642   __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm); | 
|  4643   __ StoreToSafepointRegisterSlot(reg, reg); |  4643   __ StoreToSafepointRegisterSlot(reg, reg); | 
|  4644 } |  4644 } | 
|  4645  |  4645  | 
|  4646  |  4646  | 
|  4647 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |  4647 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4679   Register reg = ToRegister(instr->result()); |  4679   Register reg = ToRegister(instr->result()); | 
|  4680   __ Move(reg, Smi::FromInt(0)); |  4680   __ Move(reg, Smi::FromInt(0)); | 
|  4681  |  4681  | 
|  4682   { |  4682   { | 
|  4683     PushSafepointRegistersScope scope(this); |  4683     PushSafepointRegistersScope scope(this); | 
|  4684     // NumberTagD uses the context from the frame, rather than |  4684     // NumberTagD uses the context from the frame, rather than | 
|  4685     // the environment's HContext or HInlinedContext value. |  4685     // the environment's HContext or HInlinedContext value. | 
|  4686     // They only call Runtime::kAllocateHeapNumber. |  4686     // They only call Runtime::kAllocateHeapNumber. | 
|  4687     // The corresponding HChange instructions are added in a phase that does |  4687     // The corresponding HChange instructions are added in a phase that does | 
|  4688     // not have easy access to the local context. |  4688     // not have easy access to the local context. | 
|  4689     __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  4689     __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  4690     __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |  4690     __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 
|  4691     RecordSafepointWithRegisters( |  4691     RecordSafepointWithRegisters( | 
|  4692         instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |  4692         instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 
|  4693     __ movq(kScratchRegister, rax); |  4693     __ movp(kScratchRegister, rax); | 
|  4694   } |  4694   } | 
|  4695   __ movq(reg, kScratchRegister); |  4695   __ movp(reg, kScratchRegister); | 
|  4696 } |  4696 } | 
|  4697  |  4697  | 
|  4698  |  4698  | 
|  4699 void LCodeGen::DoSmiTag(LSmiTag* instr) { |  4699 void LCodeGen::DoSmiTag(LSmiTag* instr) { | 
|  4700   ASSERT(instr->value()->Equals(instr->result())); |  4700   ASSERT(instr->value()->Equals(instr->result())); | 
|  4701   Register input = ToRegister(instr->value()); |  4701   Register input = ToRegister(instr->value()); | 
|  4702   ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); |  4702   ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); | 
|  4703   __ Integer32ToSmi(input, input); |  4703   __ Integer32ToSmi(input, input); | 
|  4704 } |  4704 } | 
|  4705  |  4705  | 
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4934     LOperand* input = instr->value(); |  4934     LOperand* input = instr->value(); | 
|  4935     Condition cc = masm()->CheckSmi(ToRegister(input)); |  4935     Condition cc = masm()->CheckSmi(ToRegister(input)); | 
|  4936     DeoptimizeIf(cc, instr->environment()); |  4936     DeoptimizeIf(cc, instr->environment()); | 
|  4937   } |  4937   } | 
|  4938 } |  4938 } | 
|  4939  |  4939  | 
|  4940  |  4940  | 
|  4941 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |  4941 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 
|  4942   Register input = ToRegister(instr->value()); |  4942   Register input = ToRegister(instr->value()); | 
|  4943  |  4943  | 
|  4944   __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); |  4944   __ movp(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); | 
|  4945  |  4945  | 
|  4946   if (instr->hydrogen()->is_interval_check()) { |  4946   if (instr->hydrogen()->is_interval_check()) { | 
|  4947     InstanceType first; |  4947     InstanceType first; | 
|  4948     InstanceType last; |  4948     InstanceType last; | 
|  4949     instr->hydrogen()->GetCheckInterval(&first, &last); |  4949     instr->hydrogen()->GetCheckInterval(&first, &last); | 
|  4950  |  4950  | 
|  4951     __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), |  4951     __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset), | 
|  4952             Immediate(static_cast<int8_t>(first))); |  4952             Immediate(static_cast<int8_t>(first))); | 
|  4953  |  4953  | 
|  4954     // If there is only one type in the interval check for equality. |  4954     // If there is only one type in the interval check for equality. | 
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5082  |  5082  | 
|  5083   // Check for heap number |  5083   // Check for heap number | 
|  5084   __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |  5084   __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 
|  5085          factory()->heap_number_map()); |  5085          factory()->heap_number_map()); | 
|  5086   __ j(equal, &heap_number, Label::kNear); |  5086   __ j(equal, &heap_number, Label::kNear); | 
|  5087  |  5087  | 
|  5088   // Check for undefined. Undefined is converted to zero for clamping |  5088   // Check for undefined. Undefined is converted to zero for clamping | 
|  5089   // conversions. |  5089   // conversions. | 
|  5090   __ Cmp(input_reg, factory()->undefined_value()); |  5090   __ Cmp(input_reg, factory()->undefined_value()); | 
|  5091   DeoptimizeIf(not_equal, instr->environment()); |  5091   DeoptimizeIf(not_equal, instr->environment()); | 
|  5092   __ movq(input_reg, Immediate(0)); |  5092   __ movp(input_reg, Immediate(0)); | 
|  5093   __ jmp(&done, Label::kNear); |  5093   __ jmp(&done, Label::kNear); | 
|  5094  |  5094  | 
|  5095   // Heap number |  5095   // Heap number | 
|  5096   __ bind(&heap_number); |  5096   __ bind(&heap_number); | 
|  5097   __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); |  5097   __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 
|  5098   __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); |  5098   __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); | 
|  5099   __ jmp(&done, Label::kNear); |  5099   __ jmp(&done, Label::kNear); | 
|  5100  |  5100  | 
|  5101   // smi |  5101   // smi | 
|  5102   __ bind(&is_smi); |  5102   __ bind(&is_smi); | 
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5217 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { |  5217 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { | 
|  5218   ASSERT(ToRegister(instr->context()).is(rsi)); |  5218   ASSERT(ToRegister(instr->context()).is(rsi)); | 
|  5219   Label materialized; |  5219   Label materialized; | 
|  5220   // Registers will be used as follows: |  5220   // Registers will be used as follows: | 
|  5221   // rcx = literals array. |  5221   // rcx = literals array. | 
|  5222   // rbx = regexp literal. |  5222   // rbx = regexp literal. | 
|  5223   // rax = regexp literal clone. |  5223   // rax = regexp literal clone. | 
|  5224   int literal_offset = |  5224   int literal_offset = | 
|  5225       FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); |  5225       FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); | 
|  5226   __ Move(rcx, instr->hydrogen()->literals()); |  5226   __ Move(rcx, instr->hydrogen()->literals()); | 
|  5227   __ movq(rbx, FieldOperand(rcx, literal_offset)); |  5227   __ movp(rbx, FieldOperand(rcx, literal_offset)); | 
|  5228   __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); |  5228   __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); | 
|  5229   __ j(not_equal, &materialized, Label::kNear); |  5229   __ j(not_equal, &materialized, Label::kNear); | 
|  5230  |  5230  | 
|  5231   // Create regexp literal using runtime function |  5231   // Create regexp literal using runtime function | 
|  5232   // Result will be in rax. |  5232   // Result will be in rax. | 
|  5233   __ push(rcx); |  5233   __ push(rcx); | 
|  5234   __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); |  5234   __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); | 
|  5235   __ Push(instr->hydrogen()->pattern()); |  5235   __ Push(instr->hydrogen()->pattern()); | 
|  5236   __ Push(instr->hydrogen()->flags()); |  5236   __ Push(instr->hydrogen()->flags()); | 
|  5237   CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); |  5237   CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); | 
|  5238   __ movq(rbx, rax); |  5238   __ movp(rbx, rax); | 
|  5239  |  5239  | 
|  5240   __ bind(&materialized); |  5240   __ bind(&materialized); | 
|  5241   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; |  5241   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; | 
|  5242   Label allocated, runtime_allocate; |  5242   Label allocated, runtime_allocate; | 
|  5243   __ Allocate(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); |  5243   __ Allocate(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT); | 
|  5244   __ jmp(&allocated, Label::kNear); |  5244   __ jmp(&allocated, Label::kNear); | 
|  5245  |  5245  | 
|  5246   __ bind(&runtime_allocate); |  5246   __ bind(&runtime_allocate); | 
|  5247   __ push(rbx); |  5247   __ push(rbx); | 
|  5248   __ Push(Smi::FromInt(size)); |  5248   __ Push(Smi::FromInt(size)); | 
|  5249   CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); |  5249   CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); | 
|  5250   __ pop(rbx); |  5250   __ pop(rbx); | 
|  5251  |  5251  | 
|  5252   __ bind(&allocated); |  5252   __ bind(&allocated); | 
|  5253   // Copy the content into the newly allocated memory. |  5253   // Copy the content into the newly allocated memory. | 
|  5254   // (Unroll copy loop once for better throughput). |  5254   // (Unroll copy loop once for better throughput). | 
|  5255   for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { |  5255   for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { | 
|  5256     __ movq(rdx, FieldOperand(rbx, i)); |  5256     __ movp(rdx, FieldOperand(rbx, i)); | 
|  5257     __ movq(rcx, FieldOperand(rbx, i + kPointerSize)); |  5257     __ movp(rcx, FieldOperand(rbx, i + kPointerSize)); | 
|  5258     __ movq(FieldOperand(rax, i), rdx); |  5258     __ movp(FieldOperand(rax, i), rdx); | 
|  5259     __ movq(FieldOperand(rax, i + kPointerSize), rcx); |  5259     __ movp(FieldOperand(rax, i + kPointerSize), rcx); | 
|  5260   } |  5260   } | 
|  5261   if ((size % (2 * kPointerSize)) != 0) { |  5261   if ((size % (2 * kPointerSize)) != 0) { | 
|  5262     __ movq(rdx, FieldOperand(rbx, size - kPointerSize)); |  5262     __ movp(rdx, FieldOperand(rbx, size - kPointerSize)); | 
|  5263     __ movq(FieldOperand(rax, size - kPointerSize), rdx); |  5263     __ movp(FieldOperand(rax, size - kPointerSize), rdx); | 
|  5264   } |  5264   } | 
|  5265 } |  5265 } | 
|  5266  |  5266  | 
|  5267  |  5267  | 
|  5268 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |  5268 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 
|  5269   ASSERT(ToRegister(instr->context()).is(rsi)); |  5269   ASSERT(ToRegister(instr->context()).is(rsi)); | 
|  5270   // Use the fast case closure allocation code that allocates in new |  5270   // Use the fast case closure allocation code that allocates in new | 
|  5271   // space for nested functions that don't need literals cloning. |  5271   // space for nested functions that don't need literals cloning. | 
|  5272   bool pretenure = instr->hydrogen()->pretenure(); |  5272   bool pretenure = instr->hydrogen()->pretenure(); | 
|  5273   if (!pretenure && instr->hydrogen()->has_no_literals()) { |  5273   if (!pretenure && instr->hydrogen()->has_no_literals()) { | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5355  |  5355  | 
|  5356   } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { |  5356   } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_string())) { | 
|  5357     __ CompareRoot(input, Heap::kNullValueRootIndex); |  5357     __ CompareRoot(input, Heap::kNullValueRootIndex); | 
|  5358     final_branch_condition = equal; |  5358     final_branch_condition = equal; | 
|  5359  |  5359  | 
|  5360   } else if (type_name->Equals(heap()->undefined_string())) { |  5360   } else if (type_name->Equals(heap()->undefined_string())) { | 
|  5361     __ CompareRoot(input, Heap::kUndefinedValueRootIndex); |  5361     __ CompareRoot(input, Heap::kUndefinedValueRootIndex); | 
|  5362     __ j(equal, true_label, true_distance); |  5362     __ j(equal, true_label, true_distance); | 
|  5363     __ JumpIfSmi(input, false_label, false_distance); |  5363     __ JumpIfSmi(input, false_label, false_distance); | 
|  5364     // Check for undetectable objects => true. |  5364     // Check for undetectable objects => true. | 
|  5365     __ movq(input, FieldOperand(input, HeapObject::kMapOffset)); |  5365     __ movp(input, FieldOperand(input, HeapObject::kMapOffset)); | 
|  5366     __ testb(FieldOperand(input, Map::kBitFieldOffset), |  5366     __ testb(FieldOperand(input, Map::kBitFieldOffset), | 
|  5367              Immediate(1 << Map::kIsUndetectable)); |  5367              Immediate(1 << Map::kIsUndetectable)); | 
|  5368     final_branch_condition = not_zero; |  5368     final_branch_condition = not_zero; | 
|  5369  |  5369  | 
|  5370   } else if (type_name->Equals(heap()->function_string())) { |  5370   } else if (type_name->Equals(heap()->function_string())) { | 
|  5371     STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); |  5371     STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); | 
|  5372     __ JumpIfSmi(input, false_label, false_distance); |  5372     __ JumpIfSmi(input, false_label, false_distance); | 
|  5373     __ CmpObjectType(input, JS_FUNCTION_TYPE, input); |  5373     __ CmpObjectType(input, JS_FUNCTION_TYPE, input); | 
|  5374     __ j(equal, true_label, true_distance); |  5374     __ j(equal, true_label, true_distance); | 
|  5375     __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); |  5375     __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  5401 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |  5401 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 
|  5402   Register temp = ToRegister(instr->temp()); |  5402   Register temp = ToRegister(instr->temp()); | 
|  5403  |  5403  | 
|  5404   EmitIsConstructCall(temp); |  5404   EmitIsConstructCall(temp); | 
|  5405   EmitBranch(instr, equal); |  5405   EmitBranch(instr, equal); | 
|  5406 } |  5406 } | 
|  5407  |  5407  | 
|  5408  |  5408  | 
|  5409 void LCodeGen::EmitIsConstructCall(Register temp) { |  5409 void LCodeGen::EmitIsConstructCall(Register temp) { | 
|  5410   // Get the frame pointer for the calling frame. |  5410   // Get the frame pointer for the calling frame. | 
|  5411   __ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |  5411   __ movp(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 
|  5412  |  5412  | 
|  5413   // Skip the arguments adaptor frame if it exists. |  5413   // Skip the arguments adaptor frame if it exists. | 
|  5414   Label check_frame_marker; |  5414   Label check_frame_marker; | 
|  5415   __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset), |  5415   __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset), | 
|  5416          Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |  5416          Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
|  5417   __ j(not_equal, &check_frame_marker, Label::kNear); |  5417   __ j(not_equal, &check_frame_marker, Label::kNear); | 
|  5418   __ movq(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); |  5418   __ movp(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); | 
|  5419  |  5419  | 
|  5420   // Check the marker in the calling frame. |  5420   // Check the marker in the calling frame. | 
|  5421   __ bind(&check_frame_marker); |  5421   __ bind(&check_frame_marker); | 
|  5422   __ Cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), |  5422   __ Cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), | 
|  5423          Smi::FromInt(StackFrame::CONSTRUCT)); |  5423          Smi::FromInt(StackFrame::CONSTRUCT)); | 
|  5424 } |  5424 } | 
|  5425  |  5425  | 
|  5426  |  5426  | 
|  5427 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { |  5427 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { | 
|  5428   if (!info()->IsStub()) { |  5428   if (!info()->IsStub()) { | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5467 } |  5467 } | 
|  5468  |  5468  | 
|  5469  |  5469  | 
|  5470 void LCodeGen::DoDummyUse(LDummyUse* instr) { |  5470 void LCodeGen::DoDummyUse(LDummyUse* instr) { | 
|  5471   // Nothing to see here, move on! |  5471   // Nothing to see here, move on! | 
|  5472 } |  5472 } | 
|  5473  |  5473  | 
|  5474  |  5474  | 
|  5475 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { |  5475 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { | 
|  5476   PushSafepointRegistersScope scope(this); |  5476   PushSafepointRegistersScope scope(this); | 
|  5477   __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |  5477   __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 
|  5478   __ CallRuntimeSaveDoubles(Runtime::kStackGuard); |  5478   __ CallRuntimeSaveDoubles(Runtime::kStackGuard); | 
|  5479   RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); |  5479   RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); | 
|  5480   ASSERT(instr->HasEnvironment()); |  5480   ASSERT(instr->HasEnvironment()); | 
|  5481   LEnvironment* env = instr->environment(); |  5481   LEnvironment* env = instr->environment(); | 
|  5482   safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |  5482   safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 
|  5483 } |  5483 } | 
|  5484  |  5484  | 
|  5485  |  5485  | 
|  5486 void LCodeGen::DoStackCheck(LStackCheck* instr) { |  5486 void LCodeGen::DoStackCheck(LStackCheck* instr) { | 
|  5487   class DeferredStackCheck V8_FINAL : public LDeferredCode { |  5487   class DeferredStackCheck V8_FINAL : public LDeferredCode { | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5561   Condition cc = masm()->CheckSmi(rax); |  5561   Condition cc = masm()->CheckSmi(rax); | 
|  5562   DeoptimizeIf(cc, instr->environment()); |  5562   DeoptimizeIf(cc, instr->environment()); | 
|  5563  |  5563  | 
|  5564   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |  5564   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 
|  5565   __ CmpObjectType(rax, LAST_JS_PROXY_TYPE, rcx); |  5565   __ CmpObjectType(rax, LAST_JS_PROXY_TYPE, rcx); | 
|  5566   DeoptimizeIf(below_equal, instr->environment()); |  5566   DeoptimizeIf(below_equal, instr->environment()); | 
|  5567  |  5567  | 
|  5568   Label use_cache, call_runtime; |  5568   Label use_cache, call_runtime; | 
|  5569   __ CheckEnumCache(null_value, &call_runtime); |  5569   __ CheckEnumCache(null_value, &call_runtime); | 
|  5570  |  5570  | 
|  5571   __ movq(rax, FieldOperand(rax, HeapObject::kMapOffset)); |  5571   __ movp(rax, FieldOperand(rax, HeapObject::kMapOffset)); | 
|  5572   __ jmp(&use_cache, Label::kNear); |  5572   __ jmp(&use_cache, Label::kNear); | 
|  5573  |  5573  | 
|  5574   // Get the set of properties to enumerate. |  5574   // Get the set of properties to enumerate. | 
|  5575   __ bind(&call_runtime); |  5575   __ bind(&call_runtime); | 
|  5576   __ push(rax); |  5576   __ push(rax); | 
|  5577   CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); |  5577   CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); | 
|  5578  |  5578  | 
|  5579   __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), |  5579   __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), | 
|  5580                  Heap::kMetaMapRootIndex); |  5580                  Heap::kMetaMapRootIndex); | 
|  5581   DeoptimizeIf(not_equal, instr->environment()); |  5581   DeoptimizeIf(not_equal, instr->environment()); | 
|  5582   __ bind(&use_cache); |  5582   __ bind(&use_cache); | 
|  5583 } |  5583 } | 
|  5584  |  5584  | 
|  5585  |  5585  | 
|  5586 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { |  5586 void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { | 
|  5587   Register map = ToRegister(instr->map()); |  5587   Register map = ToRegister(instr->map()); | 
|  5588   Register result = ToRegister(instr->result()); |  5588   Register result = ToRegister(instr->result()); | 
|  5589   Label load_cache, done; |  5589   Label load_cache, done; | 
|  5590   __ EnumLength(result, map); |  5590   __ EnumLength(result, map); | 
|  5591   __ Cmp(result, Smi::FromInt(0)); |  5591   __ Cmp(result, Smi::FromInt(0)); | 
|  5592   __ j(not_equal, &load_cache, Label::kNear); |  5592   __ j(not_equal, &load_cache, Label::kNear); | 
|  5593   __ LoadRoot(result, Heap::kEmptyFixedArrayRootIndex); |  5593   __ LoadRoot(result, Heap::kEmptyFixedArrayRootIndex); | 
|  5594   __ jmp(&done, Label::kNear); |  5594   __ jmp(&done, Label::kNear); | 
|  5595   __ bind(&load_cache); |  5595   __ bind(&load_cache); | 
|  5596   __ LoadInstanceDescriptors(map, result); |  5596   __ LoadInstanceDescriptors(map, result); | 
|  5597   __ movq(result, |  5597   __ movp(result, | 
|  5598           FieldOperand(result, DescriptorArray::kEnumCacheOffset)); |  5598           FieldOperand(result, DescriptorArray::kEnumCacheOffset)); | 
|  5599   __ movq(result, |  5599   __ movp(result, | 
|  5600           FieldOperand(result, FixedArray::SizeFor(instr->idx()))); |  5600           FieldOperand(result, FixedArray::SizeFor(instr->idx()))); | 
|  5601   __ bind(&done); |  5601   __ bind(&done); | 
|  5602   Condition cc = masm()->CheckSmi(result); |  5602   Condition cc = masm()->CheckSmi(result); | 
|  5603   DeoptimizeIf(cc, instr->environment()); |  5603   DeoptimizeIf(cc, instr->environment()); | 
|  5604 } |  5604 } | 
|  5605  |  5605  | 
|  5606  |  5606  | 
|  5607 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { |  5607 void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { | 
|  5608   Register object = ToRegister(instr->value()); |  5608   Register object = ToRegister(instr->value()); | 
|  5609   __ cmpq(ToRegister(instr->map()), |  5609   __ cmpq(ToRegister(instr->map()), | 
|  5610           FieldOperand(object, HeapObject::kMapOffset)); |  5610           FieldOperand(object, HeapObject::kMapOffset)); | 
|  5611   DeoptimizeIf(not_equal, instr->environment()); |  5611   DeoptimizeIf(not_equal, instr->environment()); | 
|  5612 } |  5612 } | 
|  5613  |  5613  | 
|  5614  |  5614  | 
|  5615 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { |  5615 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { | 
|  5616   Register object = ToRegister(instr->object()); |  5616   Register object = ToRegister(instr->object()); | 
|  5617   Register index = ToRegister(instr->index()); |  5617   Register index = ToRegister(instr->index()); | 
|  5618  |  5618  | 
|  5619   Label out_of_object, done; |  5619   Label out_of_object, done; | 
|  5620   __ SmiToInteger32(index, index); |  5620   __ SmiToInteger32(index, index); | 
|  5621   __ cmpl(index, Immediate(0)); |  5621   __ cmpl(index, Immediate(0)); | 
|  5622   __ j(less, &out_of_object, Label::kNear); |  5622   __ j(less, &out_of_object, Label::kNear); | 
|  5623   __ movq(object, FieldOperand(object, |  5623   __ movp(object, FieldOperand(object, | 
|  5624                                index, |  5624                                index, | 
|  5625                                times_pointer_size, |  5625                                times_pointer_size, | 
|  5626                                JSObject::kHeaderSize)); |  5626                                JSObject::kHeaderSize)); | 
|  5627   __ jmp(&done, Label::kNear); |  5627   __ jmp(&done, Label::kNear); | 
|  5628  |  5628  | 
|  5629   __ bind(&out_of_object); |  5629   __ bind(&out_of_object); | 
|  5630   __ movq(object, FieldOperand(object, JSObject::kPropertiesOffset)); |  5630   __ movp(object, FieldOperand(object, JSObject::kPropertiesOffset)); | 
|  5631   __ negl(index); |  5631   __ negl(index); | 
|  5632   // Index is now equal to out of object property index plus 1. |  5632   // Index is now equal to out of object property index plus 1. | 
|  5633   __ movq(object, FieldOperand(object, |  5633   __ movp(object, FieldOperand(object, | 
|  5634                                index, |  5634                                index, | 
|  5635                                times_pointer_size, |  5635                                times_pointer_size, | 
|  5636                                FixedArray::kHeaderSize - kPointerSize)); |  5636                                FixedArray::kHeaderSize - kPointerSize)); | 
|  5637   __ bind(&done); |  5637   __ bind(&done); | 
|  5638 } |  5638 } | 
|  5639  |  5639  | 
|  5640  |  5640  | 
|  5641 #undef __ |  5641 #undef __ | 
|  5642  |  5642  | 
|  5643 } }  // namespace v8::internal |  5643 } }  // namespace v8::internal | 
|  5644  |  5644  | 
|  5645 #endif  // V8_TARGET_ARCH_X64 |  5645 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |