| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1107 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); | 1107 RecordTypeFeedbackCell(stmt->ForInFeedbackId(), cell); |
| 1108 __ LoadHeapObject(ebx, cell); | 1108 __ LoadHeapObject(ebx, cell); |
| 1109 __ mov(FieldOperand(ebx, Cell::kValueOffset), | 1109 __ mov(FieldOperand(ebx, Cell::kValueOffset), |
| 1110 Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); | 1110 Immediate(Smi::FromInt(TypeFeedbackCells::kForInSlowCaseMarker))); |
| 1111 | 1111 |
| 1112 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check | 1112 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check |
| 1113 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object | 1113 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object |
| 1114 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 1114 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| 1115 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); | 1115 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); |
| 1116 __ j(above, &non_proxy); | 1116 __ j(above, &non_proxy); |
| 1117 __ mov(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy | 1117 __ Set(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy |
| 1118 __ bind(&non_proxy); | 1118 __ bind(&non_proxy); |
| 1119 __ push(ebx); // Smi | 1119 __ push(ebx); // Smi |
| 1120 __ push(eax); // Array | 1120 __ push(eax); // Array |
| 1121 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); | 1121 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); |
| 1122 __ push(eax); // Fixed array length (as smi). | 1122 __ push(eax); // Fixed array length (as smi). |
| 1123 __ push(Immediate(Smi::FromInt(0))); // Initial index. | 1123 __ push(Immediate(Smi::FromInt(0))); // Initial index. |
| 1124 | 1124 |
| 1125 // Generate code for doing the condition check. | 1125 // Generate code for doing the condition check. |
| 1126 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1126 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
| 1127 __ bind(&loop); | 1127 __ bind(&loop); |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 __ push(Immediate(isolate()->factory()->null_value())); | 1568 __ push(Immediate(isolate()->factory()->null_value())); |
| 1569 } else { | 1569 } else { |
| 1570 VisitForStackValue(expression); | 1570 VisitForStackValue(expression); |
| 1571 } | 1571 } |
| 1572 } | 1572 } |
| 1573 | 1573 |
| 1574 | 1574 |
| 1575 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1575 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1576 Comment cmnt(masm_, "[ ObjectLiteral"); | 1576 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 1577 | 1577 |
| 1578 int depth = 1; | 1578 expr->BuildConstantProperties(isolate()); |
| 1579 expr->BuildConstantProperties(isolate(), &depth); | |
| 1580 Handle<FixedArray> constant_properties = expr->constant_properties(); | 1579 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 1581 int flags = expr->fast_elements() | 1580 int flags = expr->fast_elements() |
| 1582 ? ObjectLiteral::kFastElements | 1581 ? ObjectLiteral::kFastElements |
| 1583 : ObjectLiteral::kNoFlags; | 1582 : ObjectLiteral::kNoFlags; |
| 1584 flags |= expr->has_function() | 1583 flags |= expr->has_function() |
| 1585 ? ObjectLiteral::kHasFunction | 1584 ? ObjectLiteral::kHasFunction |
| 1586 : ObjectLiteral::kNoFlags; | 1585 : ObjectLiteral::kNoFlags; |
| 1587 int properties_count = constant_properties->length() / 2; | 1586 int properties_count = constant_properties->length() / 2; |
| 1588 if ((FLAG_track_double_fields && expr->may_store_doubles()) || | 1587 if ((FLAG_track_double_fields && expr->may_store_doubles()) || |
| 1589 depth > 1 || Serializer::enabled() || | 1588 expr->depth() > 1 || Serializer::enabled() || |
| 1590 flags != ObjectLiteral::kFastElements || | 1589 flags != ObjectLiteral::kFastElements || |
| 1591 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1590 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
| 1592 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1591 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1593 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); | 1592 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); |
| 1594 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1593 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
| 1595 __ push(Immediate(constant_properties)); | 1594 __ push(Immediate(constant_properties)); |
| 1596 __ push(Immediate(Smi::FromInt(flags))); | 1595 __ push(Immediate(Smi::FromInt(flags))); |
| 1597 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1596 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
| 1598 } else { | 1597 } else { |
| 1599 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1598 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1698 context()->PlugTOS(); | 1697 context()->PlugTOS(); |
| 1699 } else { | 1698 } else { |
| 1700 context()->Plug(eax); | 1699 context()->Plug(eax); |
| 1701 } | 1700 } |
| 1702 } | 1701 } |
| 1703 | 1702 |
| 1704 | 1703 |
| 1705 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1704 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1706 Comment cmnt(masm_, "[ ArrayLiteral"); | 1705 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1707 | 1706 |
| 1708 int depth = 1; | 1707 expr->BuildConstantElements(isolate()); |
| 1709 expr->BuildConstantElements(isolate(), &depth); | |
| 1710 ZoneList<Expression*>* subexprs = expr->values(); | 1708 ZoneList<Expression*>* subexprs = expr->values(); |
| 1711 int length = subexprs->length(); | 1709 int length = subexprs->length(); |
| 1712 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1710 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1713 ASSERT_EQ(2, constant_elements->length()); | 1711 ASSERT_EQ(2, constant_elements->length()); |
| 1714 ElementsKind constant_elements_kind = | 1712 ElementsKind constant_elements_kind = |
| 1715 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); | 1713 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); |
| 1716 bool has_constant_fast_elements = | 1714 bool has_constant_fast_elements = |
| 1717 IsFastObjectElementsKind(constant_elements_kind); | 1715 IsFastObjectElementsKind(constant_elements_kind); |
| 1718 Handle<FixedArrayBase> constant_elements_values( | 1716 Handle<FixedArrayBase> constant_elements_values( |
| 1719 FixedArrayBase::cast(constant_elements->get(1))); | 1717 FixedArrayBase::cast(constant_elements->get(1))); |
| 1720 | 1718 |
| 1721 Heap* heap = isolate()->heap(); | 1719 Heap* heap = isolate()->heap(); |
| 1722 if (has_constant_fast_elements && | 1720 if (has_constant_fast_elements && |
| 1723 constant_elements_values->map() == heap->fixed_cow_array_map()) { | 1721 constant_elements_values->map() == heap->fixed_cow_array_map()) { |
| 1724 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot | 1722 // If the elements are already FAST_*_ELEMENTS, the boilerplate cannot |
| 1725 // change, so it's possible to specialize the stub in advance. | 1723 // change, so it's possible to specialize the stub in advance. |
| 1726 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1); | 1724 __ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1); |
| 1727 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1725 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1728 __ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset)); | 1726 __ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset)); |
| 1729 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); | 1727 __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); |
| 1730 __ mov(ecx, Immediate(constant_elements)); | 1728 __ mov(ecx, Immediate(constant_elements)); |
| 1731 FastCloneShallowArrayStub stub( | 1729 FastCloneShallowArrayStub stub( |
| 1732 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, | 1730 FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, |
| 1733 DONT_TRACK_ALLOCATION_SITE, | 1731 DONT_TRACK_ALLOCATION_SITE, |
| 1734 length); | 1732 length); |
| 1735 __ CallStub(&stub); | 1733 __ CallStub(&stub); |
| 1736 } else if (depth > 1 || Serializer::enabled() || | 1734 } else if (expr->depth() > 1 || Serializer::enabled() || |
| 1737 length > FastCloneShallowArrayStub::kMaximumClonedLength) { | 1735 length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
| 1738 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1736 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1739 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); | 1737 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); |
| 1740 __ push(Immediate(Smi::FromInt(expr->literal_index()))); | 1738 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
| 1741 __ push(Immediate(constant_elements)); | 1739 __ push(Immediate(constant_elements)); |
| 1742 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); | 1740 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); |
| 1743 } else { | 1741 } else { |
| 1744 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || | 1742 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) || |
| 1745 FLAG_smi_only_arrays); | 1743 FLAG_smi_only_arrays); |
| 1746 FastCloneShallowArrayStub::Mode mode = | 1744 FastCloneShallowArrayStub::Mode mode = |
| (...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3291 VisitForStackValue(args->at(1)); | 3289 VisitForStackValue(args->at(1)); |
| 3292 VisitForStackValue(args->at(2)); | 3290 VisitForStackValue(args->at(2)); |
| 3293 __ CallRuntime(Runtime::kLog, 2); | 3291 __ CallRuntime(Runtime::kLog, 2); |
| 3294 } | 3292 } |
| 3295 // Finally, we're expected to leave a value on the top of the stack. | 3293 // Finally, we're expected to leave a value on the top of the stack. |
| 3296 __ mov(eax, isolate()->factory()->undefined_value()); | 3294 __ mov(eax, isolate()->factory()->undefined_value()); |
| 3297 context()->Plug(eax); | 3295 context()->Plug(eax); |
| 3298 } | 3296 } |
| 3299 | 3297 |
| 3300 | 3298 |
| 3301 void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) { | |
| 3302 ASSERT(expr->arguments()->length() == 0); | |
| 3303 | |
| 3304 Label slow_allocate_heapnumber; | |
| 3305 Label heapnumber_allocated; | |
| 3306 | |
| 3307 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber); | |
| 3308 __ jmp(&heapnumber_allocated); | |
| 3309 | |
| 3310 __ bind(&slow_allocate_heapnumber); | |
| 3311 // Allocate a heap number. | |
| 3312 __ CallRuntime(Runtime::kNumberAlloc, 0); | |
| 3313 __ mov(edi, eax); | |
| 3314 | |
| 3315 __ bind(&heapnumber_allocated); | |
| 3316 | |
| 3317 __ PrepareCallCFunction(1, ebx); | |
| 3318 __ mov(eax, ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX)); | |
| 3319 __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset)); | |
| 3320 __ mov(Operand(esp, 0), eax); | |
| 3321 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | |
| 3322 | |
| 3323 // Convert 32 random bits in eax to 0.(32 random bits) in a double | |
| 3324 // by computing: | |
| 3325 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). | |
| 3326 // This is implemented on both SSE2 and FPU. | |
| 3327 if (CpuFeatures::IsSupported(SSE2)) { | |
| 3328 CpuFeatureScope fscope(masm(), SSE2); | |
| 3329 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. | |
| 3330 __ movd(xmm1, ebx); | |
| 3331 __ movd(xmm0, eax); | |
| 3332 __ cvtss2sd(xmm1, xmm1); | |
| 3333 __ xorps(xmm0, xmm1); | |
| 3334 __ subsd(xmm0, xmm1); | |
| 3335 __ movsd(FieldOperand(edi, HeapNumber::kValueOffset), xmm0); | |
| 3336 } else { | |
| 3337 // 0x4130000000000000 is 1.0 x 2^20 as a double. | |
| 3338 __ mov(FieldOperand(edi, HeapNumber::kExponentOffset), | |
| 3339 Immediate(0x41300000)); | |
| 3340 __ mov(FieldOperand(edi, HeapNumber::kMantissaOffset), eax); | |
| 3341 __ fld_d(FieldOperand(edi, HeapNumber::kValueOffset)); | |
| 3342 __ mov(FieldOperand(edi, HeapNumber::kMantissaOffset), Immediate(0)); | |
| 3343 __ fld_d(FieldOperand(edi, HeapNumber::kValueOffset)); | |
| 3344 __ fsubp(1); | |
| 3345 __ fstp_d(FieldOperand(edi, HeapNumber::kValueOffset)); | |
| 3346 } | |
| 3347 __ mov(eax, edi); | |
| 3348 context()->Plug(eax); | |
| 3349 } | |
| 3350 | |
| 3351 | |
| 3352 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | 3299 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 3353 // Load the arguments on the stack and call the stub. | 3300 // Load the arguments on the stack and call the stub. |
| 3354 SubStringStub stub; | 3301 SubStringStub stub; |
| 3355 ZoneList<Expression*>* args = expr->arguments(); | 3302 ZoneList<Expression*>* args = expr->arguments(); |
| 3356 ASSERT(args->length() == 3); | 3303 ASSERT(args->length() == 3); |
| 3357 VisitForStackValue(args->at(0)); | 3304 VisitForStackValue(args->at(0)); |
| 3358 VisitForStackValue(args->at(1)); | 3305 VisitForStackValue(args->at(1)); |
| 3359 VisitForStackValue(args->at(2)); | 3306 VisitForStackValue(args->at(2)); |
| 3360 __ CallStub(&stub); | 3307 __ CallStub(&stub); |
| 3361 context()->Plug(eax); | 3308 context()->Plug(eax); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3433 __ jmp(&done); | 3380 __ jmp(&done); |
| 3434 } | 3381 } |
| 3435 | 3382 |
| 3436 __ bind(¬_date_object); | 3383 __ bind(¬_date_object); |
| 3437 __ CallRuntime(Runtime::kThrowNotDateError, 0); | 3384 __ CallRuntime(Runtime::kThrowNotDateError, 0); |
| 3438 __ bind(&done); | 3385 __ bind(&done); |
| 3439 context()->Plug(result); | 3386 context()->Plug(result); |
| 3440 } | 3387 } |
| 3441 | 3388 |
| 3442 | 3389 |
| 3443 void FullCodeGenerator::EmitSeqStringSetCharCheck(Register string, | |
| 3444 Register index, | |
| 3445 Register value, | |
| 3446 uint32_t encoding_mask) { | |
| 3447 __ test(index, Immediate(kSmiTagMask)); | |
| 3448 __ Check(zero, kNonSmiIndex); | |
| 3449 __ test(value, Immediate(kSmiTagMask)); | |
| 3450 __ Check(zero, kNonSmiValue); | |
| 3451 | |
| 3452 __ cmp(index, FieldOperand(string, String::kLengthOffset)); | |
| 3453 __ Check(less, kIndexIsTooLarge); | |
| 3454 | |
| 3455 __ cmp(index, Immediate(Smi::FromInt(0))); | |
| 3456 __ Check(greater_equal, kIndexIsNegative); | |
| 3457 | |
| 3458 __ push(value); | |
| 3459 __ mov(value, FieldOperand(string, HeapObject::kMapOffset)); | |
| 3460 __ movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset)); | |
| 3461 | |
| 3462 __ and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); | |
| 3463 __ cmp(value, Immediate(encoding_mask)); | |
| 3464 __ Check(equal, kUnexpectedStringType); | |
| 3465 __ pop(value); | |
| 3466 } | |
| 3467 | |
| 3468 | |
| 3469 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { | 3390 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { |
| 3470 ZoneList<Expression*>* args = expr->arguments(); | 3391 ZoneList<Expression*>* args = expr->arguments(); |
| 3471 ASSERT_EQ(3, args->length()); | 3392 ASSERT_EQ(3, args->length()); |
| 3472 | 3393 |
| 3473 Register string = eax; | 3394 Register string = eax; |
| 3474 Register index = ebx; | 3395 Register index = ebx; |
| 3475 Register value = ecx; | 3396 Register value = ecx; |
| 3476 | 3397 |
| 3477 VisitForStackValue(args->at(1)); // index | 3398 VisitForStackValue(args->at(1)); // index |
| 3478 VisitForStackValue(args->at(2)); // value | 3399 VisitForStackValue(args->at(2)); // value |
| 3400 VisitForAccumulatorValue(args->at(0)); // string |
| 3401 |
| 3479 __ pop(value); | 3402 __ pop(value); |
| 3480 __ pop(index); | 3403 __ pop(index); |
| 3481 VisitForAccumulatorValue(args->at(0)); // string | |
| 3482 | |
| 3483 | 3404 |
| 3484 if (FLAG_debug_code) { | 3405 if (FLAG_debug_code) { |
| 3485 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 3406 __ test(value, Immediate(kSmiTagMask)); |
| 3486 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); | 3407 __ ThrowIf(not_zero, kNonSmiValue); |
| 3408 __ test(index, Immediate(kSmiTagMask)); |
| 3409 __ ThrowIf(not_zero, kNonSmiValue); |
| 3487 } | 3410 } |
| 3488 | 3411 |
| 3489 __ SmiUntag(value); | 3412 __ SmiUntag(value); |
| 3490 __ SmiUntag(index); | 3413 __ SmiUntag(index); |
| 3414 |
| 3415 if (FLAG_debug_code) { |
| 3416 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
| 3417 __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); |
| 3418 } |
| 3419 |
| 3491 __ mov_b(FieldOperand(string, index, times_1, SeqOneByteString::kHeaderSize), | 3420 __ mov_b(FieldOperand(string, index, times_1, SeqOneByteString::kHeaderSize), |
| 3492 value); | 3421 value); |
| 3493 context()->Plug(string); | 3422 context()->Plug(string); |
| 3494 } | 3423 } |
| 3495 | 3424 |
| 3496 | 3425 |
| 3497 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { | 3426 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { |
| 3498 ZoneList<Expression*>* args = expr->arguments(); | 3427 ZoneList<Expression*>* args = expr->arguments(); |
| 3499 ASSERT_EQ(3, args->length()); | 3428 ASSERT_EQ(3, args->length()); |
| 3500 | 3429 |
| 3501 Register string = eax; | 3430 Register string = eax; |
| 3502 Register index = ebx; | 3431 Register index = ebx; |
| 3503 Register value = ecx; | 3432 Register value = ecx; |
| 3504 | 3433 |
| 3505 VisitForStackValue(args->at(1)); // index | 3434 VisitForStackValue(args->at(1)); // index |
| 3506 VisitForStackValue(args->at(2)); // value | 3435 VisitForStackValue(args->at(2)); // value |
| 3436 VisitForAccumulatorValue(args->at(0)); // string |
| 3507 __ pop(value); | 3437 __ pop(value); |
| 3508 __ pop(index); | 3438 __ pop(index); |
| 3509 VisitForAccumulatorValue(args->at(0)); // string | |
| 3510 | 3439 |
| 3511 if (FLAG_debug_code) { | 3440 if (FLAG_debug_code) { |
| 3441 __ test(value, Immediate(kSmiTagMask)); |
| 3442 __ ThrowIf(not_zero, kNonSmiValue); |
| 3443 __ test(index, Immediate(kSmiTagMask)); |
| 3444 __ ThrowIf(not_zero, kNonSmiValue); |
| 3445 __ SmiUntag(index); |
| 3512 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 3446 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
| 3513 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); | 3447 __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); |
| 3448 __ SmiTag(index); |
| 3514 } | 3449 } |
| 3515 | 3450 |
| 3516 __ SmiUntag(value); | 3451 __ SmiUntag(value); |
| 3517 // No need to untag a smi for two-byte addressing. | 3452 // No need to untag a smi for two-byte addressing. |
| 3518 __ mov_w(FieldOperand(string, index, times_1, SeqTwoByteString::kHeaderSize), | 3453 __ mov_w(FieldOperand(string, index, times_1, SeqTwoByteString::kHeaderSize), |
| 3519 value); | 3454 value); |
| 3520 context()->Plug(string); | 3455 context()->Plug(string); |
| 3521 } | 3456 } |
| 3522 | 3457 |
| 3523 | 3458 |
| (...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4968 | 4903 |
| 4969 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4904 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4970 Assembler::target_address_at(call_target_address)); | 4905 Assembler::target_address_at(call_target_address)); |
| 4971 return OSR_AFTER_STACK_CHECK; | 4906 return OSR_AFTER_STACK_CHECK; |
| 4972 } | 4907 } |
| 4973 | 4908 |
| 4974 | 4909 |
| 4975 } } // namespace v8::internal | 4910 } } // namespace v8::internal |
| 4976 | 4911 |
| 4977 #endif // V8_TARGET_ARCH_IA32 | 4912 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |