Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 1238143002: [stubs] Optimize LoadGlobalViaContextStub and StoreGlobalViaContextStub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix ARM typo. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_MIPS 7 #if V8_TARGET_ARCH_MIPS
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 5252 matching lines...) Expand 10 before | Expand all | Expand 10 after
5263 5263
5264 Label fast_elements_case; 5264 Label fast_elements_case;
5265 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS)); 5265 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS));
5266 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 5266 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
5267 5267
5268 __ bind(&fast_elements_case); 5268 __ bind(&fast_elements_case);
5269 GenerateCase(masm, FAST_ELEMENTS); 5269 GenerateCase(masm, FAST_ELEMENTS);
5270 } 5270 }
5271 5271
5272 5272
5273 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) {
5274 Register context_reg = cp;
5275 Register slot_reg = a2;
5276 Register name_reg = a3;
5277 Register result_reg = v0;
5278 Label slow_case;
5279
5280 // Go up context chain to the script context.
5281 for (int i = 0; i < depth(); ++i) {
5282 __ lw(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX));
5283 context_reg = result_reg;
5284 }
5285
5286 // Load the PropertyCell value at the specified slot.
5287 __ sll(at, slot_reg, kPointerSizeLog2);
5288 __ Addu(at, at, Operand(cp));
Igor Sheludko 2015/07/24 11:10:01 We should load the cell from context_reg here.
5289 __ Addu(at, at, Context::SlotOffset(0));
5290 __ lw(result_reg, MemOperand(at));
5291 __ lw(result_reg, FieldMemOperand(result_reg, PropertyCell::kValueOffset));
5292
5293 // Check that value is not the_hole.
5294 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
5295 __ Branch(&slow_case, eq, result_reg, Operand(at));
5296 __ Ret();
5297
5298 // Fallback to the runtime.
5299 __ bind(&slow_case);
5300 __ SmiTag(slot_reg);
5301 __ Drop(1); // Pop return address.
5302 __ Push(slot_reg, name_reg, result_reg);
5303 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 2, 1);
5304 }
5305
5306
5307 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) {
5308 Register context_reg = cp;
5309 Register slot_reg = a2;
5310 Register name_reg = a3;
5311 Register value_reg = a0;
5312 Register cell_reg = t0;
5313 Register cell_details_reg = t1;
5314 Label fast_heapobject_case, fast_smi_case, slow_case;
5315
5316 if (FLAG_debug_code) {
5317 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
5318 __ Check(ne, kUnexpectedValue, value_reg, Operand(at));
5319 __ AssertName(name_reg);
5320 }
5321
5322 // Go up context chain to the script context.
5323 for (int i = 0; i < depth(); ++i) {
5324 __ lw(cell_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX));
5325 context_reg = cell_reg;
5326 }
5327
5328 // Load the PropertyCell at the specified slot.
5329 __ sll(at, slot_reg, kPointerSizeLog2);
5330 __ Addu(at, at, Operand(cp));
Igor Sheludko 2015/07/24 11:10:01 Same here.
5331 __ Addu(at, at, Context::SlotOffset(0));
5332 __ lw(cell_reg, MemOperand(at));
5333
5334 // Load PropertyDetails for the cell (actually only the cell_type and kind).
5335 __ lw(cell_details_reg,
5336 FieldMemOperand(cell_reg, PropertyCell::kDetailsOffset));
5337 __ SmiUntag(cell_details_reg);
5338 __ And(cell_details_reg, cell_details_reg,
5339 PropertyDetails::PropertyCellTypeField::kMask |
5340 PropertyDetails::KindField::kMask);
5341
5342 // Check if PropertyCell holds mutable data.
5343 Label not_mutable_data;
5344 __ Branch(&not_mutable_data, ne, cell_details_reg,
5345 Operand(PropertyDetails::PropertyCellTypeField::encode(
5346 PropertyCellType::kMutable) |
5347 PropertyDetails::KindField::encode(kData)));
5348 __ JumpIfSmi(value_reg, &fast_smi_case);
5349 __ bind(&fast_heapobject_case);
5350 __ sw(value_reg, FieldMemOperand(cell_reg, PropertyCell::kValueOffset));
5351 __ RecordWriteField(cell_reg, PropertyCell::kValueOffset, value_reg,
5352 cell_details_reg, kRAHasNotBeenSaved, kDontSaveFPRegs,
5353 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
5354 // RecordWriteField clobbers the value register, so we need to reload.
5355 __ lw(value_reg, FieldMemOperand(cell_reg, PropertyCell::kValueOffset));
5356 __ Ret();
5357 __ bind(&not_mutable_data);
5358
5359 // Check if PropertyCell value matches the new value (relevant for Constant,
5360 // ConstantType and Undefined cells).
5361 Label not_same_value;
5362 __ lw(at, FieldMemOperand(cell_reg, PropertyCell::kValueOffset));
5363 __ Branch(&not_same_value, ne, value_reg, Operand(at));
5364 if (FLAG_debug_code) {
5365 Label done;
5366 // This can only be true for Constant, ConstantType and Undefined cells,
5367 // because we never store the_hole via this stub.
5368 __ Branch(&done, eq, cell_details_reg,
5369 Operand(PropertyDetails::PropertyCellTypeField::encode(
5370 PropertyCellType::kConstant) |
5371 PropertyDetails::KindField::encode(kData)));
5372 __ Branch(&done, eq, cell_details_reg,
5373 Operand(PropertyDetails::PropertyCellTypeField::encode(
5374 PropertyCellType::kConstantType) |
5375 PropertyDetails::KindField::encode(kData)));
5376 __ Check(eq, kUnexpectedValue, cell_details_reg,
5377 Operand(PropertyDetails::PropertyCellTypeField::encode(
5378 PropertyCellType::kUndefined) |
5379 PropertyDetails::KindField::encode(kData)));
5380 __ bind(&done);
5381 }
5382 __ Ret();
5383 __ bind(&not_same_value);
5384
5385 // Check if PropertyCell contains data with constant type.
5386 __ Branch(&slow_case, ne, cell_details_reg,
5387 Operand(PropertyDetails::PropertyCellTypeField::encode(
5388 PropertyCellType::kConstantType) |
5389 PropertyDetails::KindField::encode(kData)));
5390
5391 // Now either both old and new values must be SMIs or both must be heap
5392 // objects with same map.
5393 Label value_is_heap_object;
5394 Register cell_value_reg = cell_details_reg;
5395 __ lw(cell_value_reg, FieldMemOperand(cell_reg, PropertyCell::kValueOffset));
5396 __ JumpIfNotSmi(value_reg, &value_is_heap_object);
5397 __ JumpIfNotSmi(cell_value_reg, &slow_case);
5398 // Old and new values are SMIs, no need for a write barrier here.
5399 __ bind(&fast_smi_case);
5400 __ Ret(USE_DELAY_SLOT);
5401 __ sw(value_reg, FieldMemOperand(cell_reg, PropertyCell::kValueOffset));
5402 __ bind(&value_is_heap_object);
5403 __ JumpIfSmi(cell_value_reg, &slow_case);
5404 Register cell_value_map_reg = cell_value_reg;
5405 __ lw(cell_value_map_reg,
5406 FieldMemOperand(cell_value_reg, HeapObject::kMapOffset));
5407 __ Branch(&fast_heapobject_case, eq, cell_value_map_reg,
5408 FieldMemOperand(value_reg, HeapObject::kMapOffset));
5409
5410 // Fallback to the runtime.
5411 __ bind(&slow_case);
5412 __ SmiTag(slot_reg);
5413 __ Drop(1); // Pop return address.
5414 __ Push(slot_reg, name_reg, value_reg, cell_reg);
5415 __ TailCallRuntime(is_strict(language_mode())
5416 ? Runtime::kStoreGlobalViaContext_Strict
5417 : Runtime::kStoreGlobalViaContext_Sloppy,
5418 3, 1);
5419 }
5420
5421
5273 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { 5422 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
5274 return ref0.address() - ref1.address(); 5423 return ref0.address() - ref1.address();
5275 } 5424 }
5276 5425
5277 5426
5278 // Calls an API function. Allocates HandleScope, extracts returned value 5427 // Calls an API function. Allocates HandleScope, extracts returned value
5279 // from handle and propagates exceptions. Restores context. stack_space 5428 // from handle and propagates exceptions. Restores context. stack_space
5280 // - space to be unwound on exit (includes the call JS arguments space and 5429 // - space to be unwound on exit (includes the call JS arguments space and
5281 // the additional space allocated for the fast call). 5430 // the additional space allocated for the fast call).
5282 static void CallApiFunctionAndReturn( 5431 static void CallApiFunctionAndReturn(
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
5572 MemOperand(fp, 6 * kPointerSize), NULL); 5721 MemOperand(fp, 6 * kPointerSize), NULL);
5573 } 5722 }
5574 5723
5575 5724
5576 #undef __ 5725 #undef __
5577 5726
5578 } // namespace internal 5727 } // namespace internal
5579 } // namespace v8 5728 } // namespace v8
5580 5729
5581 #endif // V8_TARGET_ARCH_MIPS 5730 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698