| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 } | 161 } |
| 162 | 162 |
| 163 private: | 163 private: |
| 164 Condition cond_; | 164 Condition cond_; |
| 165 const Register& value_; | 165 const Register& value_; |
| 166 uint64_t mask_; | 166 uint64_t mask_; |
| 167 }; | 167 }; |
| 168 | 168 |
| 169 | 169 |
| 170 void LCodeGen::WriteTranslation(LEnvironment* environment, | 170 void LCodeGen::WriteTranslation(LEnvironment* environment, |
| 171 Translation* translation, | 171 Translation* translation) { |
| 172 int* pushed_arguments_index, | |
| 173 int* pushed_arguments_count) { | |
| 174 if (environment == NULL) return; | 172 if (environment == NULL) return; |
| 175 | 173 |
| 176 // The translation includes one command per value in the environment. | 174 // The translation includes one command per value in the environment. |
| 177 int translation_size = environment->values()->length(); | 175 int translation_size = environment->translation_size(); |
| 178 // The output frame height does not include the parameters. | 176 // The output frame height does not include the parameters. |
| 179 int height = translation_size - environment->parameter_count(); | 177 int height = translation_size - environment->parameter_count(); |
| 180 | 178 |
| 181 // Function parameters are arguments to the outermost environment. The | 179 WriteTranslation(environment->outer(), translation); |
| 182 // arguments index points to the first element of a sequence of tagged | |
| 183 // values on the stack that represent the arguments. This needs to be | |
| 184 // kept in sync with the LArgumentsElements implementation. | |
| 185 *pushed_arguments_index = -environment->parameter_count(); | |
| 186 *pushed_arguments_count = environment->parameter_count(); | |
| 187 | |
| 188 WriteTranslation(environment->outer(), | |
| 189 translation, | |
| 190 pushed_arguments_index, | |
| 191 pushed_arguments_count); | |
| 192 bool has_closure_id = !info()->closure().is_null() && | 180 bool has_closure_id = !info()->closure().is_null() && |
| 193 !info()->closure().is_identical_to(environment->closure()); | 181 !info()->closure().is_identical_to(environment->closure()); |
| 194 int closure_id = has_closure_id | 182 int closure_id = has_closure_id |
| 195 ? DefineDeoptimizationLiteral(environment->closure()) | 183 ? DefineDeoptimizationLiteral(environment->closure()) |
| 196 : Translation::kSelfLiteralId; | 184 : Translation::kSelfLiteralId; |
| 197 | 185 |
| 198 switch (environment->frame_type()) { | 186 switch (environment->frame_type()) { |
| 199 case JS_FUNCTION: | 187 case JS_FUNCTION: |
| 200 translation->BeginJSFrame(environment->ast_id(), closure_id, height); | 188 translation->BeginJSFrame(environment->ast_id(), closure_id, height); |
| 201 break; | 189 break; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 215 case STUB: | 203 case STUB: |
| 216 translation->BeginCompiledStubFrame(); | 204 translation->BeginCompiledStubFrame(); |
| 217 break; | 205 break; |
| 218 case ARGUMENTS_ADAPTOR: | 206 case ARGUMENTS_ADAPTOR: |
| 219 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); | 207 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); |
| 220 break; | 208 break; |
| 221 default: | 209 default: |
| 222 UNREACHABLE(); | 210 UNREACHABLE(); |
| 223 } | 211 } |
| 224 | 212 |
| 225 // Inlined frames which push their arguments cause the index to be | |
| 226 // bumped and another stack area to be used for materialization, | |
| 227 // otherwise actual argument values are unknown for inlined frames. | |
| 228 bool arguments_known = true; | |
| 229 int arguments_index = *pushed_arguments_index; | |
| 230 int arguments_count = *pushed_arguments_count; | |
| 231 if (environment->entry() != NULL) { | |
| 232 arguments_known = environment->entry()->arguments_pushed(); | |
| 233 arguments_index = arguments_index < 0 | |
| 234 ? GetStackSlotCount() : arguments_index + arguments_count; | |
| 235 arguments_count = environment->entry()->arguments_count() + 1; | |
| 236 if (environment->entry()->arguments_pushed()) { | |
| 237 *pushed_arguments_index = arguments_index; | |
| 238 *pushed_arguments_count = arguments_count; | |
| 239 } | |
| 240 } | |
| 241 | |
| 242 for (int i = 0; i < translation_size; ++i) { | 213 for (int i = 0; i < translation_size; ++i) { |
| 243 LOperand* value = environment->values()->at(i); | 214 LOperand* value = environment->values()->at(i); |
| 244 // spilled_registers_ and spilled_double_registers_ are either | 215 // spilled_registers_ and spilled_double_registers_ are either |
| 245 // both NULL or both set. | 216 // both NULL or both set. |
| 246 if ((environment->spilled_registers() != NULL) && (value != NULL)) { | 217 if ((environment->spilled_registers() != NULL) && (value != NULL)) { |
| 247 if (value->IsRegister() && | 218 if (value->IsRegister() && |
| 248 (environment->spilled_registers()[value->index()] != NULL)) { | 219 (environment->spilled_registers()[value->index()] != NULL)) { |
| 249 translation->MarkDuplicate(); | 220 translation->MarkDuplicate(); |
| 250 AddToTranslation(translation, | 221 AddToTranslation(translation, |
| 251 environment->spilled_registers()[value->index()], | 222 environment->spilled_registers()[value->index()], |
| 252 environment->HasTaggedValueAt(i), | 223 environment->HasTaggedValueAt(i), |
| 253 environment->HasUint32ValueAt(i), | 224 environment->HasUint32ValueAt(i)); |
| 254 arguments_known, | |
| 255 arguments_index, | |
| 256 arguments_count); | |
| 257 } else if ( | 225 } else if ( |
| 258 value->IsDoubleRegister() && | 226 value->IsDoubleRegister() && |
| 259 (environment->spilled_double_registers()[value->index()] != NULL)) { | 227 (environment->spilled_double_registers()[value->index()] != NULL)) { |
| 260 translation->MarkDuplicate(); | 228 translation->MarkDuplicate(); |
| 261 AddToTranslation( | 229 AddToTranslation( |
| 262 translation, | 230 translation, |
| 263 environment->spilled_double_registers()[value->index()], | 231 environment->spilled_double_registers()[value->index()], |
| 264 false, | 232 false, |
| 265 false, | 233 false); |
| 266 arguments_known, | |
| 267 arguments_index, | |
| 268 arguments_count); | |
| 269 } | 234 } |
| 270 } | 235 } |
| 271 | 236 |
| 237 // TODO(mstarzinger): Introduce marker operands to indicate that this value |
| 238 // is not present and must be reconstructed from the deoptimizer. Currently |
| 239 // this is only used for the arguments object. |
| 240 if (value == NULL) { |
| 241 int arguments_count = environment->values()->length() - translation_size; |
| 242 translation->BeginArgumentsObject(arguments_count); |
| 243 for (int i = 0; i < arguments_count; ++i) { |
| 244 LOperand* value = environment->values()->at(translation_size + i); |
| 245 ASSERT(environment->spilled_registers() == NULL || |
| 246 !value->IsRegister() || |
| 247 environment->spilled_registers()[value->index()] == NULL); |
| 248 ASSERT(environment->spilled_registers() == NULL || |
| 249 !value->IsDoubleRegister() || |
| 250 environment->spilled_double_registers()[value->index()] == NULL); |
| 251 AddToTranslation(translation, |
| 252 value, |
| 253 environment->HasTaggedValueAt(translation_size + i), |
| 254 environment->HasUint32ValueAt(translation_size + i)); |
| 255 } |
| 256 continue; |
| 257 } |
| 258 |
| 272 AddToTranslation(translation, | 259 AddToTranslation(translation, |
| 273 value, | 260 value, |
| 274 environment->HasTaggedValueAt(i), | 261 environment->HasTaggedValueAt(i), |
| 275 environment->HasUint32ValueAt(i), | 262 environment->HasUint32ValueAt(i)); |
| 276 arguments_known, | |
| 277 arguments_index, | |
| 278 arguments_count); | |
| 279 } | 263 } |
| 280 } | 264 } |
| 281 | 265 |
| 282 | 266 |
| 283 void LCodeGen::AddToTranslation(Translation* translation, | 267 void LCodeGen::AddToTranslation(Translation* translation, |
| 284 LOperand* op, | 268 LOperand* op, |
| 285 bool is_tagged, | 269 bool is_tagged, |
| 286 bool is_uint32, | 270 bool is_uint32) { |
| 287 bool arguments_known, | 271 if (op->IsStackSlot()) { |
| 288 int arguments_index, | |
| 289 int arguments_count) { | |
| 290 if (op == NULL) { | |
| 291 // TODO(twuerthinger): Introduce marker operands to indicate that this value | |
| 292 // is not present and must be reconstructed from the deoptimizer. Currently | |
| 293 // this is only used for the arguments object. | |
| 294 translation->StoreArgumentsObject( | |
| 295 arguments_known, arguments_index, arguments_count); | |
| 296 } else if (op->IsStackSlot()) { | |
| 297 if (is_tagged) { | 272 if (is_tagged) { |
| 298 translation->StoreStackSlot(op->index()); | 273 translation->StoreStackSlot(op->index()); |
| 299 } else if (is_uint32) { | 274 } else if (is_uint32) { |
| 300 translation->StoreUint32StackSlot(op->index()); | 275 translation->StoreUint32StackSlot(op->index()); |
| 301 } else { | 276 } else { |
| 302 translation->StoreInt32StackSlot(op->index()); | 277 translation->StoreInt32StackSlot(op->index()); |
| 303 } | 278 } |
| 304 } else if (op->IsDoubleStackSlot()) { | 279 } else if (op->IsDoubleStackSlot()) { |
| 305 translation->StoreDoubleStackSlot(op->index()); | 280 translation->StoreDoubleStackSlot(op->index()); |
| 306 } else if (op->IsArgument()) { | 281 } else if (op->IsArgument()) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 337 deoptimization_literals_.Add(literal, zone()); | 312 deoptimization_literals_.Add(literal, zone()); |
| 338 return result; | 313 return result; |
| 339 } | 314 } |
| 340 | 315 |
| 341 | 316 |
| 342 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, | 317 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, |
| 343 Safepoint::DeoptMode mode) { | 318 Safepoint::DeoptMode mode) { |
| 344 if (!environment->HasBeenRegistered()) { | 319 if (!environment->HasBeenRegistered()) { |
| 345 int frame_count = 0; | 320 int frame_count = 0; |
| 346 int jsframe_count = 0; | 321 int jsframe_count = 0; |
| 347 int args_index = 0; | |
| 348 int args_count = 0; | |
| 349 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { | 322 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { |
| 350 ++frame_count; | 323 ++frame_count; |
| 351 if (e->frame_type() == JS_FUNCTION) { | 324 if (e->frame_type() == JS_FUNCTION) { |
| 352 ++jsframe_count; | 325 ++jsframe_count; |
| 353 } | 326 } |
| 354 } | 327 } |
| 355 Translation translation(&translations_, frame_count, jsframe_count, zone()); | 328 Translation translation(&translations_, frame_count, jsframe_count, zone()); |
| 356 WriteTranslation(environment, &translation, &args_index, &args_count); | 329 WriteTranslation(environment, &translation); |
| 357 int deoptimization_index = deoptimizations_.length(); | 330 int deoptimization_index = deoptimizations_.length(); |
| 358 int pc_offset = masm()->pc_offset(); | 331 int pc_offset = masm()->pc_offset(); |
| 359 environment->Register(deoptimization_index, | 332 environment->Register(deoptimization_index, |
| 360 translation.index(), | 333 translation.index(), |
| 361 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); | 334 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); |
| 362 deoptimizations_.Add(environment, zone()); | 335 deoptimizations_.Add(environment, zone()); |
| 363 } | 336 } |
| 364 } | 337 } |
| 365 | 338 |
| 366 | 339 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 __ Mov(x2, Operand(instr->hydrogen()->property_cell())); | 404 __ Mov(x2, Operand(instr->hydrogen()->property_cell())); |
| 432 | 405 |
| 433 ElementsKind kind = instr->hydrogen()->elements_kind(); | 406 ElementsKind kind = instr->hydrogen()->elements_kind(); |
| 434 bool disable_allocation_sites = | 407 bool disable_allocation_sites = |
| 435 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE); | 408 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE); |
| 436 | 409 |
| 437 if (instr->arity() == 0) { | 410 if (instr->arity() == 0) { |
| 438 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites); | 411 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites); |
| 439 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 412 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 440 } else if (instr->arity() == 1) { | 413 } else if (instr->arity() == 1) { |
| 414 Label done; |
| 415 if (IsFastPackedElementsKind(kind)) { |
| 416 Label packed_case; |
| 417 |
| 418 // We might need to create a holey array; look at the first argument. |
| 419 __ Peek(x10, 0); |
| 420 __ Cbz(x10, &packed_case); |
| 421 |
| 422 ElementsKind holey_kind = GetHoleyElementsKind(kind); |
| 423 ArraySingleArgumentConstructorStub stub(holey_kind, |
| 424 disable_allocation_sites); |
| 425 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 426 __ B(&done); |
| 427 __ Bind(&packed_case); |
| 428 } |
| 429 |
| 441 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites); | 430 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites); |
| 442 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 431 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 432 __ Bind(&done); |
| 443 } else { | 433 } else { |
| 444 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites); | 434 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites); |
| 445 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 435 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 446 } | 436 } |
| 447 | 437 |
| 448 ASSERT(ToRegister(instr->result()).is(x0)); | 438 ASSERT(ToRegister(instr->result()).is(x0)); |
| 449 } | 439 } |
| 450 | 440 |
| 451 | 441 |
| 452 void LCodeGen::CallRuntime(const Runtime::Function* function, | 442 void LCodeGen::CallRuntime(const Runtime::Function* function, |
| (...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2199 } | 2189 } |
| 2200 } | 2190 } |
| 2201 | 2191 |
| 2202 | 2192 |
| 2203 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 2193 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
| 2204 Register reg = ToRegister(instr->value()); | 2194 Register reg = ToRegister(instr->value()); |
| 2205 Handle<JSFunction> target = instr->hydrogen()->target(); | 2195 Handle<JSFunction> target = instr->hydrogen()->target(); |
| 2206 AllowDeferredHandleDereference smi_check; | 2196 AllowDeferredHandleDereference smi_check; |
| 2207 if (isolate()->heap()->InNewSpace(*target)) { | 2197 if (isolate()->heap()->InNewSpace(*target)) { |
| 2208 Register temp = ToRegister(instr->temp()); | 2198 Register temp = ToRegister(instr->temp()); |
| 2209 Handle<JSGlobalPropertyCell> cell = | 2199 Handle<Cell> cell = isolate()->factory()->NewPropertyCell(target); |
| 2210 isolate()->factory()->NewJSGlobalPropertyCell(target); | |
| 2211 __ Mov(temp, Operand(Handle<Object>(cell))); | 2200 __ Mov(temp, Operand(Handle<Object>(cell))); |
| 2212 __ Ldr(temp, FieldMemOperand(temp, JSGlobalPropertyCell::kValueOffset)); | 2201 __ Ldr(temp, FieldMemOperand(temp, Cell::kValueOffset)); |
| 2213 __ Cmp(reg, temp); | 2202 __ Cmp(reg, temp); |
| 2214 } else { | 2203 } else { |
| 2215 __ Cmp(reg, Operand(target)); | 2204 __ Cmp(reg, Operand(target)); |
| 2216 } | 2205 } |
| 2217 DeoptimizeIf(ne, instr->environment()); | 2206 DeoptimizeIf(ne, instr->environment()); |
| 2218 } | 2207 } |
| 2219 | 2208 |
| 2220 | 2209 |
| 2221 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { | 2210 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { |
| 2222 EnsureSpaceForLazyDeopt(); | 2211 EnsureSpaceForLazyDeopt(); |
| (...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3024 Deoptimize(instr->environment()); | 3013 Deoptimize(instr->environment()); |
| 3025 | 3014 |
| 3026 // All done. | 3015 // All done. |
| 3027 __ Bind(&done); | 3016 __ Bind(&done); |
| 3028 } | 3017 } |
| 3029 | 3018 |
| 3030 | 3019 |
| 3031 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { | 3020 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { |
| 3032 Register result = ToRegister(instr->result()); | 3021 Register result = ToRegister(instr->result()); |
| 3033 __ Mov(result, Operand(Handle<Object>(instr->hydrogen()->cell()))); | 3022 __ Mov(result, Operand(Handle<Object>(instr->hydrogen()->cell()))); |
| 3034 __ Ldr(result, FieldMemOperand(result, JSGlobalPropertyCell::kValueOffset)); | 3023 __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset)); |
| 3035 if (instr->hydrogen()->RequiresHoleCheck()) { | 3024 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3036 DeoptimizeIfRoot( | 3025 DeoptimizeIfRoot( |
| 3037 result, Heap::kTheHoleValueRootIndex, instr->environment()); | 3026 result, Heap::kTheHoleValueRootIndex, instr->environment()); |
| 3038 } | 3027 } |
| 3039 } | 3028 } |
| 3040 | 3029 |
| 3041 | 3030 |
| 3042 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 3031 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 3043 ASSERT(ToRegister(instr->global_object()).Is(x0)); | 3032 ASSERT(ToRegister(instr->global_object()).Is(x0)); |
| 3044 ASSERT(ToRegister(instr->result()).Is(x0)); | 3033 ASSERT(ToRegister(instr->result()).Is(x0)); |
| (...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4452 | 4441 |
| 4453 // Load the cell. | 4442 // Load the cell. |
| 4454 __ Mov(cell, Operand(instr->hydrogen()->cell())); | 4443 __ Mov(cell, Operand(instr->hydrogen()->cell())); |
| 4455 | 4444 |
| 4456 // If the cell we are storing to contains the hole it could have | 4445 // If the cell we are storing to contains the hole it could have |
| 4457 // been deleted from the property dictionary. In that case, we need | 4446 // been deleted from the property dictionary. In that case, we need |
| 4458 // to update the property details in the property dictionary to mark | 4447 // to update the property details in the property dictionary to mark |
| 4459 // it as no longer deleted. We deoptimize in that case. | 4448 // it as no longer deleted. We deoptimize in that case. |
| 4460 if (instr->hydrogen()->RequiresHoleCheck()) { | 4449 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 4461 Register payload = ToRegister(instr->temp2()); | 4450 Register payload = ToRegister(instr->temp2()); |
| 4462 __ Ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); | 4451 __ Ldr(payload, FieldMemOperand(cell, Cell::kValueOffset)); |
| 4463 DeoptimizeIfRoot( | 4452 DeoptimizeIfRoot( |
| 4464 payload, Heap::kTheHoleValueRootIndex, instr->environment()); | 4453 payload, Heap::kTheHoleValueRootIndex, instr->environment()); |
| 4465 } | 4454 } |
| 4466 | 4455 |
| 4467 // Store the value. | 4456 // Store the value. |
| 4468 __ Str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); | 4457 __ Str(value, FieldMemOperand(cell, Cell::kValueOffset)); |
| 4469 // Cells are always rescanned, so no write barrier here. | 4458 // Cells are always rescanned, so no write barrier here. |
| 4470 } | 4459 } |
| 4471 | 4460 |
| 4472 | 4461 |
| 4473 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { | 4462 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { |
| 4474 ASSERT(ToRegister(instr->global_object()).Is(x1)); | 4463 ASSERT(ToRegister(instr->global_object()).Is(x1)); |
| 4475 ASSERT(ToRegister(instr->value()).Is(x0)); | 4464 ASSERT(ToRegister(instr->value()).Is(x0)); |
| 4476 | 4465 |
| 4477 __ Mov(x2, Operand(instr->name())); | 4466 __ Mov(x2, Operand(instr->name())); |
| 4478 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 4467 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5282 __ Bind(&out_of_object); | 5271 __ Bind(&out_of_object); |
| 5283 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5272 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5284 // Index is equal to negated out of object property index plus 1. | 5273 // Index is equal to negated out of object property index plus 1. |
| 5285 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5274 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5286 __ Ldr(result, FieldMemOperand(result, | 5275 __ Ldr(result, FieldMemOperand(result, |
| 5287 FixedArray::kHeaderSize - kPointerSize)); | 5276 FixedArray::kHeaderSize - kPointerSize)); |
| 5288 __ Bind(&done); | 5277 __ Bind(&done); |
| 5289 } | 5278 } |
| 5290 | 5279 |
| 5291 } } // namespace v8::internal | 5280 } } // namespace v8::internal |
| OLD | NEW |