OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 5283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5294 | 5294 |
5295 Label fast_elements_case; | 5295 Label fast_elements_case; |
5296 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS)); | 5296 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS)); |
5297 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 5297 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
5298 | 5298 |
5299 __ bind(&fast_elements_case); | 5299 __ bind(&fast_elements_case); |
5300 GenerateCase(masm, FAST_ELEMENTS); | 5300 GenerateCase(masm, FAST_ELEMENTS); |
5301 } | 5301 } |
5302 | 5302 |
5303 | 5303 |
5304 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { | |
5305 Register context_reg = cp; | |
5306 Register slot_reg = a2; | |
5307 Register name_reg = a3; | |
5308 Register result_reg = v0; | |
5309 Label slow_case; | |
5310 | |
5311 // Go up context chain to the script context. | |
5312 for (int i = 0; i < depth(); ++i) { | |
5313 __ lw(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | |
5314 context_reg = result_reg; | |
5315 } | |
5316 | |
5317 // Load the PropertyCell value at the specified slot. | |
5318 __ dsll(at, slot_reg, kPointerSizeLog2); | |
5319 __ Daddu(at, at, Operand(cp)); | |
Igor Sheludko
2015/07/24 11:10:01
We should load the cell from context_reg context.
| |
5320 __ Daddu(at, at, Context::SlotOffset(0)); | |
5321 __ ld(result_reg, MemOperand(at)); | |
5322 __ ld(result_reg, FieldMemOperand(result_reg, PropertyCell::kValueOffset)); | |
5323 | |
5324 // Check that value is not the_hole. | |
5325 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | |
5326 __ Branch(&slow_case, eq, result_reg, Operand(at)); | |
5327 __ Ret(); | |
5328 | |
5329 // Fallback to the runtime. | |
5330 __ bind(&slow_case); | |
5331 __ SmiTag(slot_reg); | |
5332 __ Drop(1); // Pop return address. | |
5333 __ Push(slot_reg, name_reg, result_reg); | |
5334 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 2, 1); | |
5335 } | |
5336 | |
5337 | |
5338 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { | |
5339 Register context_reg = cp; | |
5340 Register slot_reg = a2; | |
5341 Register name_reg = a3; | |
5342 Register value_reg = a0; | |
5343 Register cell_reg = a4; | |
5344 Register cell_details_reg = a5; | |
5345 Label fast_heapobject_case, fast_smi_case, slow_case; | |
5346 | |
5347 if (FLAG_debug_code) { | |
5348 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | |
5349 __ Check(ne, kUnexpectedValue, value_reg, Operand(at)); | |
5350 __ AssertName(name_reg); | |
5351 } | |
5352 | |
5353 // Go up context chain to the script context. | |
5354 for (int i = 0; i < depth(); ++i) { | |
5355 __ ld(cell_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | |
5356 context_reg = cell_reg; | |
5357 } | |
5358 | |
5359 // Load the PropertyCell at the specified slot. | |
5360 __ dsll(at, slot_reg, kPointerSizeLog2); | |
5361 __ Daddu(at, at, Operand(cp)); | |
Igor Sheludko
2015/07/24 11:10:01
Same here.
| |
5362 __ Daddu(at, at, Context::SlotOffset(0)); | |
5363 __ ld(cell_reg, MemOperand(at)); | |
5364 | |
5365 // Load PropertyDetails for the cell (actually only the cell_type and kind). | |
5366 __ ld(cell_details_reg, | |
5367 FieldMemOperand(cell_reg, PropertyCell::kDetailsOffset)); | |
5368 __ SmiUntag(cell_details_reg); | |
5369 __ And(cell_details_reg, cell_details_reg, | |
5370 PropertyDetails::PropertyCellTypeField::kMask | | |
5371 PropertyDetails::KindField::kMask); | |
5372 | |
5373 // Check if PropertyCell holds mutable data. | |
5374 Label not_mutable_data; | |
5375 __ Branch(¬_mutable_data, ne, cell_details_reg, | |
5376 Operand(PropertyDetails::PropertyCellTypeField::encode( | |
5377 PropertyCellType::kMutable) | | |
5378 PropertyDetails::KindField::encode(kData))); | |
5379 __ JumpIfSmi(value_reg, &fast_smi_case); | |
5380 __ bind(&fast_heapobject_case); | |
5381 __ sd(value_reg, FieldMemOperand(cell_reg, PropertyCell::kValueOffset)); | |
5382 __ RecordWriteField(cell_reg, PropertyCell::kValueOffset, value_reg, | |
5383 cell_details_reg, kRAHasNotBeenSaved, kDontSaveFPRegs, | |
5384 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
5385 // RecordWriteField clobbers the value register, so we need to reload. | |
5386 __ Ret(USE_DELAY_SLOT); | |
5387 __ ld(value_reg, FieldMemOperand(cell_reg, PropertyCell::kValueOffset)); | |
5388 __ bind(¬_mutable_data); | |
5389 | |
5390 // Check if PropertyCell value matches the new value (relevant for Constant, | |
5391 // ConstantType and Undefined cells). | |
5392 Label not_same_value; | |
5393 __ ld(at, FieldMemOperand(cell_reg, PropertyCell::kValueOffset)); | |
5394 __ Branch(¬_same_value, ne, value_reg, Operand(at)); | |
5395 if (FLAG_debug_code) { | |
5396 Label done; | |
5397 // This can only be true for Constant, ConstantType and Undefined cells, | |
5398 // because we never store the_hole via this stub. | |
5399 __ Branch(&done, eq, cell_details_reg, | |
5400 Operand(PropertyDetails::PropertyCellTypeField::encode( | |
5401 PropertyCellType::kConstant) | | |
5402 PropertyDetails::KindField::encode(kData))); | |
5403 __ Branch(&done, eq, cell_details_reg, | |
5404 Operand(PropertyDetails::PropertyCellTypeField::encode( | |
5405 PropertyCellType::kConstantType) | | |
5406 PropertyDetails::KindField::encode(kData))); | |
5407 __ Check(eq, kUnexpectedValue, cell_details_reg, | |
5408 Operand(PropertyDetails::PropertyCellTypeField::encode( | |
5409 PropertyCellType::kUndefined) | | |
5410 PropertyDetails::KindField::encode(kData))); | |
5411 __ bind(&done); | |
5412 } | |
5413 __ Ret(); | |
5414 __ bind(¬_same_value); | |
5415 | |
5416 // Check if PropertyCell contains data with constant type. | |
5417 __ Branch(&slow_case, ne, cell_details_reg, | |
5418 Operand(PropertyDetails::PropertyCellTypeField::encode( | |
5419 PropertyCellType::kConstantType) | | |
5420 PropertyDetails::KindField::encode(kData))); | |
5421 | |
5422 // Now either both old and new values must be SMIs or both must be heap | |
5423 // objects with same map. | |
5424 Label value_is_heap_object; | |
5425 Register cell_value_reg = cell_details_reg; | |
5426 __ ld(cell_value_reg, FieldMemOperand(cell_reg, PropertyCell::kValueOffset)); | |
5427 __ JumpIfNotSmi(value_reg, &value_is_heap_object); | |
5428 __ JumpIfNotSmi(cell_value_reg, &slow_case); | |
5429 // Old and new values are SMIs, no need for a write barrier here. | |
5430 __ bind(&fast_smi_case); | |
5431 __ Ret(USE_DELAY_SLOT); | |
5432 __ sd(value_reg, FieldMemOperand(cell_reg, PropertyCell::kValueOffset)); | |
5433 __ bind(&value_is_heap_object); | |
5434 __ JumpIfSmi(cell_value_reg, &slow_case); | |
5435 Register cell_value_map_reg = cell_value_reg; | |
5436 __ ld(cell_value_map_reg, | |
5437 FieldMemOperand(cell_value_reg, HeapObject::kMapOffset)); | |
5438 __ Branch(&fast_heapobject_case, eq, cell_value_map_reg, | |
5439 FieldMemOperand(value_reg, HeapObject::kMapOffset)); | |
5440 | |
5441 // Fallback to the runtime. | |
5442 __ bind(&slow_case); | |
5443 __ SmiTag(slot_reg); | |
5444 __ Drop(1); // Pop return address. | |
5445 __ Push(slot_reg, name_reg, value_reg, cell_reg); | |
5446 __ TailCallRuntime(is_strict(language_mode()) | |
5447 ? Runtime::kStoreGlobalViaContext_Strict | |
5448 : Runtime::kStoreGlobalViaContext_Sloppy, | |
5449 3, 1); | |
5450 } | |
5451 | |
5452 | |
5304 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | 5453 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { |
5305 int64_t offset = (ref0.address() - ref1.address()); | 5454 int64_t offset = (ref0.address() - ref1.address()); |
5306 DCHECK(static_cast<int>(offset) == offset); | 5455 DCHECK(static_cast<int>(offset) == offset); |
5307 return static_cast<int>(offset); | 5456 return static_cast<int>(offset); |
5308 } | 5457 } |
5309 | 5458 |
5310 | 5459 |
5311 // Calls an API function. Allocates HandleScope, extracts returned value | 5460 // Calls an API function. Allocates HandleScope, extracts returned value |
5312 // from handle and propagates exceptions. Restores context. stack_space | 5461 // from handle and propagates exceptions. Restores context. stack_space |
5313 // - space to be unwound on exit (includes the call JS arguments space and | 5462 // - space to be unwound on exit (includes the call JS arguments space and |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5604 MemOperand(fp, 6 * kPointerSize), NULL); | 5753 MemOperand(fp, 6 * kPointerSize), NULL); |
5605 } | 5754 } |
5606 | 5755 |
5607 | 5756 |
5608 #undef __ | 5757 #undef __ |
5609 | 5758 |
5610 } // namespace internal | 5759 } // namespace internal |
5611 } // namespace v8 | 5760 } // namespace v8 |
5612 | 5761 |
5613 #endif // V8_TARGET_ARCH_MIPS64 | 5762 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |