| OLD | NEW | 
|    1 // Copyright 2011 the V8 project authors. All rights reserved. |    1 // Copyright 2011 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 12 matching lines...) Expand all  Loading... | 
|   23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |   23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|   24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |   24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|   25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |   25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|   26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |   26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|   27  |   27  | 
|   28 #include "v8.h" |   28 #include "v8.h" | 
|   29  |   29  | 
|   30 #if defined(V8_TARGET_ARCH_IA32) |   30 #if defined(V8_TARGET_ARCH_IA32) | 
|   31  |   31  | 
|   32 #include "codegen.h" |   32 #include "codegen.h" | 
 |   33 #include "macro-assembler.h" | 
|   33  |   34  | 
|   34 namespace v8 { |   35 namespace v8 { | 
|   35 namespace internal { |   36 namespace internal { | 
|   36  |   37  | 
|   37  |   38  | 
|   38 // ------------------------------------------------------------------------- |   39 // ------------------------------------------------------------------------- | 
|   39 // Platform-specific RuntimeCallHelper functions. |   40 // Platform-specific RuntimeCallHelper functions. | 
|   40  |   41  | 
|   41 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { |   42 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { | 
|   42   masm->EnterFrame(StackFrame::INTERNAL); |   43   masm->EnterFrame(StackFrame::INTERNAL); | 
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  258   masm.GetCode(&desc); |  259   masm.GetCode(&desc); | 
|  259   ASSERT(desc.reloc_size == 0); |  260   ASSERT(desc.reloc_size == 0); | 
|  260  |  261  | 
|  261   CPU::FlushICache(buffer, actual_size); |  262   CPU::FlushICache(buffer, actual_size); | 
|  262   OS::ProtectCode(buffer, actual_size); |  263   OS::ProtectCode(buffer, actual_size); | 
|  263   return FUNCTION_CAST<OS::MemCopyFunction>(buffer); |  264   return FUNCTION_CAST<OS::MemCopyFunction>(buffer); | 
|  264 } |  265 } | 
|  265  |  266  | 
|  266 #undef __ |  267 #undef __ | 
|  267  |  268  | 
 |  269 // ------------------------------------------------------------------------- | 
 |  270 // Code generators | 
 |  271  | 
 |  272 #define __ ACCESS_MASM(masm) | 
 |  273  | 
 |  274 void ElementsTransitionGenerator::GenerateSmiOnlyToObject( | 
 |  275     MacroAssembler* masm) { | 
 |  276   // ----------- S t a t e ------------- | 
 |  277   //  -- eax    : value | 
 |  278   //  -- ebx    : target map | 
 |  279   //  -- ecx    : key | 
 |  280   //  -- edx    : receiver | 
 |  281   //  -- esp[0] : return address | 
 |  282   // ----------------------------------- | 
 |  283   // Set transitioned map. | 
 |  284   __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx); | 
 |  285   __ RecordWriteField(edx, | 
 |  286                       HeapObject::kMapOffset, | 
 |  287                       ebx, | 
 |  288                       edi, | 
 |  289                       kDontSaveFPRegs, | 
 |  290                       EMIT_REMEMBERED_SET, | 
 |  291                       OMIT_SMI_CHECK); | 
 |  292 } | 
 |  293  | 
 |  294  | 
 |  295 void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( | 
 |  296     MacroAssembler* masm, Label* fail) { | 
 |  297   // ----------- S t a t e ------------- | 
 |  298   //  -- eax    : value | 
 |  299   //  -- ebx    : target map | 
 |  300   //  -- ecx    : key | 
 |  301   //  -- edx    : receiver | 
 |  302   //  -- esp[0] : return address | 
 |  303   // ----------------------------------- | 
 |  304   Label loop, entry, convert_hole, gc_required; | 
 |  305   __ push(eax); | 
 |  306   __ push(ebx); | 
 |  307  | 
 |  308   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 
 |  309   __ mov(edi, FieldOperand(edi, FixedArray::kLengthOffset)); | 
 |  310  | 
 |  311   // Allocate new FixedDoubleArray. | 
 |  312   // edx: receiver | 
 |  313   // edi: length of source FixedArray (smi-tagged) | 
 |  314   __ lea(esi, Operand(edi, times_4, FixedDoubleArray::kHeaderSize)); | 
 |  315   __ AllocateInNewSpace(esi, eax, ebx, no_reg, &gc_required, TAG_OBJECT); | 
 |  316  | 
 |  317   // eax: destination FixedDoubleArray | 
 |  318   // edi: number of elements | 
 |  319   // edx: receiver | 
 |  320   __ mov(FieldOperand(eax, HeapObject::kMapOffset), | 
 |  321          Immediate(masm->isolate()->factory()->fixed_double_array_map())); | 
 |  322   __ mov(FieldOperand(eax, FixedDoubleArray::kLengthOffset), edi); | 
 |  323   __ mov(esi, FieldOperand(edx, JSObject::kElementsOffset)); | 
 |  324   // Replace receiver's backing store with newly created FixedDoubleArray. | 
 |  325   __ mov(FieldOperand(edx, JSObject::kElementsOffset), eax); | 
 |  326   __ mov(ebx, eax); | 
 |  327   __ RecordWriteField(edx, | 
 |  328                       JSObject::kElementsOffset, | 
 |  329                       ebx, | 
 |  330                       edi, | 
 |  331                       kDontSaveFPRegs, | 
 |  332                       EMIT_REMEMBERED_SET, | 
 |  333                       OMIT_SMI_CHECK); | 
 |  334  | 
 |  335   __ mov(edi, FieldOperand(esi, FixedArray::kLengthOffset)); | 
 |  336  | 
 |  337   // Prepare for conversion loop. | 
 |  338   ExternalReference canonical_the_hole_nan_reference = | 
 |  339       ExternalReference::address_of_the_hole_nan(); | 
 |  340   XMMRegister the_hole_nan = xmm1; | 
 |  341   if (CpuFeatures::IsSupported(SSE2)) { | 
 |  342     CpuFeatures::Scope use_sse2(SSE2); | 
 |  343     __ movdbl(the_hole_nan, | 
 |  344               Operand::StaticVariable(canonical_the_hole_nan_reference)); | 
 |  345   } | 
 |  346   __ jmp(&entry); | 
 |  347  | 
 |  348   // Call into runtime if GC is required. | 
 |  349   __ bind(&gc_required); | 
 |  350   // Restore registers before jumping into runtime. | 
 |  351   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
 |  352   __ pop(ebx); | 
 |  353   __ pop(eax); | 
 |  354   __ jmp(fail); | 
 |  355  | 
 |  356   // Convert and copy elements | 
 |  357   // esi: source FixedArray | 
 |  358   // edi: number of elements to convert/copy | 
 |  359   __ bind(&loop); | 
 |  360   __ sub(edi, Immediate(Smi::FromInt(1))); | 
 |  361   __ mov(ebx, FieldOperand(esi, edi, times_2, FixedArray::kHeaderSize)); | 
 |  362   // ebx: current element from source | 
 |  363   // edi: index of current element | 
 |  364   __ JumpIfNotSmi(ebx, &convert_hole); | 
 |  365  | 
 |  366   // Normal smi, convert it to double and store. | 
 |  367   __ SmiUntag(ebx); | 
 |  368   if (CpuFeatures::IsSupported(SSE2)) { | 
 |  369     CpuFeatures::Scope fscope(SSE2); | 
 |  370     __ cvtsi2sd(xmm0, ebx); | 
 |  371     __ movdbl(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize), | 
 |  372               xmm0); | 
 |  373   } else { | 
 |  374     __ push(ebx); | 
 |  375     __ fild_s(Operand(esp, 0)); | 
 |  376     __ pop(ebx); | 
 |  377     __ fstp_d(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize)); | 
 |  378   } | 
 |  379   __ jmp(&entry); | 
 |  380  | 
 |  381   // Found hole, store hole_nan_as_double instead. | 
 |  382   __ bind(&convert_hole); | 
 |  383   if (CpuFeatures::IsSupported(SSE2)) { | 
 |  384     CpuFeatures::Scope use_sse2(SSE2); | 
 |  385     __ movdbl(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize), | 
 |  386               the_hole_nan); | 
 |  387   } else { | 
 |  388     __ fld_d(Operand::StaticVariable(canonical_the_hole_nan_reference)); | 
 |  389     __ fstp_d(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize)); | 
 |  390   } | 
 |  391  | 
 |  392   __ bind(&entry); | 
 |  393   __ test(edi, edi); | 
 |  394   __ j(not_zero, &loop); | 
 |  395  | 
 |  396   __ pop(ebx); | 
 |  397   __ pop(eax); | 
 |  398   // eax: value | 
 |  399   // ebx: target map | 
 |  400   // Set transitioned map. | 
 |  401   __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx); | 
 |  402   __ RecordWriteField(edx, | 
 |  403                       HeapObject::kMapOffset, | 
 |  404                       ebx, | 
 |  405                       edi, | 
 |  406                       kDontSaveFPRegs, | 
 |  407                       EMIT_REMEMBERED_SET, | 
 |  408                       OMIT_SMI_CHECK); | 
 |  409   // Restore esi. | 
 |  410   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
 |  411 } | 
 |  412  | 
 |  413  | 
 |  414 void ElementsTransitionGenerator::GenerateDoubleToObject( | 
 |  415     MacroAssembler* masm, Label* fail) { | 
 |  416   // ----------- S t a t e ------------- | 
 |  417   //  -- eax    : value | 
 |  418   //  -- ebx    : target map | 
 |  419   //  -- ecx    : key | 
 |  420   //  -- edx    : receiver | 
 |  421   //  -- esp[0] : return address | 
 |  422   // ----------------------------------- | 
 |  423   Label loop, entry, convert_hole, gc_required; | 
 |  424   __ push(eax); | 
 |  425   __ push(edx); | 
 |  426   __ push(ebx); | 
 |  427  | 
 |  428   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 
 |  429   __ mov(ebx, FieldOperand(edi, FixedDoubleArray::kLengthOffset)); | 
 |  430  | 
 |  431   // Allocate new FixedArray. | 
 |  432   // ebx: length of source FixedDoubleArray (smi-tagged) | 
 |  433   __ lea(edi, Operand(ebx, times_2, FixedArray::kHeaderSize)); | 
 |  434   __ AllocateInNewSpace(edi, eax, esi, no_reg, &gc_required, TAG_OBJECT); | 
 |  435  | 
 |  436   // eax: destination FixedArray | 
 |  437   // ebx: number of elements | 
 |  438   __ mov(FieldOperand(eax, HeapObject::kMapOffset), | 
 |  439          Immediate(masm->isolate()->factory()->fixed_array_map())); | 
 |  440   __ mov(FieldOperand(eax, FixedArray::kLengthOffset), ebx); | 
 |  441   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 
 |  442  | 
 |  443   __ jmp(&entry); | 
 |  444  | 
 |  445   // Call into runtime if GC is required. | 
 |  446   __ bind(&gc_required); | 
 |  447   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
 |  448   __ pop(ebx); | 
 |  449   __ pop(edx); | 
 |  450   __ pop(eax); | 
 |  451   __ jmp(fail); | 
 |  452  | 
 |  453   // Box doubles into heap numbers. | 
 |  454   // edi: source FixedDoubleArray | 
 |  455   // eax: destination FixedArray | 
 |  456   __ bind(&loop); | 
 |  457   __ sub(ebx, Immediate(Smi::FromInt(1))); | 
 |  458   // ebx: index of current element (smi-tagged) | 
 |  459   uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); | 
 |  460   __ cmp(FieldOperand(edi, ebx, times_4, offset), Immediate(kHoleNanUpper32)); | 
 |  461   __ j(equal, &convert_hole); | 
 |  462  | 
 |  463   // Non-hole double, copy value into a heap number. | 
 |  464   __ AllocateHeapNumber(edx, esi, no_reg, &gc_required); | 
 |  465   // edx: new heap number | 
 |  466   if (CpuFeatures::IsSupported(SSE2)) { | 
 |  467     CpuFeatures::Scope fscope(SSE2); | 
 |  468     __ movdbl(xmm0, | 
 |  469               FieldOperand(edi, ebx, times_4, FixedDoubleArray::kHeaderSize)); | 
 |  470     __ movdbl(FieldOperand(edx, HeapNumber::kValueOffset), xmm0); | 
 |  471   } else { | 
 |  472     __ mov(esi, FieldOperand(edi, ebx, times_4, FixedDoubleArray::kHeaderSize)); | 
 |  473     __ mov(FieldOperand(edx, HeapNumber::kValueOffset), esi); | 
 |  474     __ mov(esi, FieldOperand(edi, ebx, times_4, offset)); | 
 |  475     __ mov(FieldOperand(edx, HeapNumber::kValueOffset + kPointerSize), esi); | 
 |  476   } | 
 |  477   __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize), edx); | 
 |  478   __ mov(esi, ebx); | 
 |  479   __ RecordWriteArray(eax, | 
 |  480                       edx, | 
 |  481                       esi, | 
 |  482                       kDontSaveFPRegs, | 
 |  483                       EMIT_REMEMBERED_SET, | 
 |  484                       OMIT_SMI_CHECK); | 
 |  485   __ jmp(&entry, Label::kNear); | 
 |  486  | 
 |  487   // Replace the-hole NaN with the-hole pointer. | 
 |  488   __ bind(&convert_hole); | 
 |  489   __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize), | 
 |  490          masm->isolate()->factory()->the_hole_value()); | 
 |  491  | 
 |  492   __ bind(&entry); | 
 |  493   __ test(ebx, ebx); | 
 |  494   __ j(not_zero, &loop); | 
 |  495  | 
 |  496   __ pop(ebx); | 
 |  497   __ pop(edx); | 
 |  498   // ebx: target map | 
 |  499   // edx: receiver | 
 |  500   // Set transitioned map. | 
 |  501   __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx); | 
 |  502   __ RecordWriteField(edx, | 
 |  503                       HeapObject::kMapOffset, | 
 |  504                       ebx, | 
 |  505                       edi, | 
 |  506                       kDontSaveFPRegs, | 
 |  507                       EMIT_REMEMBERED_SET, | 
 |  508                       OMIT_SMI_CHECK); | 
 |  509   // Replace receiver's backing store with newly created and filled FixedArray. | 
 |  510   __ mov(FieldOperand(edx, JSObject::kElementsOffset), eax); | 
 |  511   __ RecordWriteField(edx, | 
 |  512                       JSObject::kElementsOffset, | 
 |  513                       eax, | 
 |  514                       edi, | 
 |  515                       kDontSaveFPRegs, | 
 |  516                       EMIT_REMEMBERED_SET, | 
 |  517                       OMIT_SMI_CHECK); | 
 |  518  | 
 |  519   // Restore registers. | 
 |  520   __ pop(eax); | 
 |  521   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
 |  522 } | 
 |  523  | 
 |  524 #undef __ | 
 |  525  | 
|  268 } }  // namespace v8::internal |  526 } }  // namespace v8::internal | 
|  269  |  527  | 
|  270 #endif  // V8_TARGET_ARCH_IA32 |  528 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |